htpolynet 2.11.3__tar.gz → 2.11.4__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.11.3 → htpolynet-2.11.4}/CHANGELOG.md +167 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/PKG-INFO +1 -1
- {htpolynet-2.11.3 → htpolynet-2.11.4}/ROADMAP.md +167 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/install.rst +34 -3
- {htpolynet-2.11.3 → htpolynet-2.11.4}/pyproject.toml +1 -1
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/projectfilesystem.py +31 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/runtime.py +70 -2
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/cure/ringcontroller.py +172 -8
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/cure/triplesearch.py +134 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/schema/base.yaml +105 -7
- htpolynet-2.11.4/tests/unit/test_checkout_shadowing.py +50 -0
- htpolynet-2.11.4/tests/unit/test_overlong_bond_report.py +82 -0
- htpolynet-2.11.4/tests/unit/test_ring_cure_schema.py +105 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_ringcontroller.py +115 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_triplesearch.py +65 -2
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.claude/settings.json +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.claude/skills/htpolynet/SKILL.md +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.envrc +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.github/workflows/conda-forge-sync.yml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.github/workflows/docker.yml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.github/workflows/docs.yml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.github/workflows/release.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.github/workflows/test.yml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.gitignore +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/.readthedocs.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/CITATION.cff +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/CLAUDE.md +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/LICENSE +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/MANIFEST.in +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/README.md +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docker/Dockerfile +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docker/compose.yml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docker/docker-entrypoint.sh +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/Makefile +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/README.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/make.bat +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/requirements.txt +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/_static/.gitkeep +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/_static/htpolynet-favicon.ico +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/_static/htpolynet-landing.jpg +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/_static/htpolynet-logo-dark.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/_static/htpolynet-logo-light.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/changelog.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/conf.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/0-liquid-styrene/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/0-liquid-styrene/results.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/0-liquid-styrene/run.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/configuration.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/introduction.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/monomer.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/STY.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/STYCC.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/pics/styrene-polymerization.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/postsim.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/reactions.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/results.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/1-polystyrene/run.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/BPA.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/GMA.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/HIE.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.eps +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.fig +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/p1-traces.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.eps +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.fig +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-epoxy.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-labelled.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-2d.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-labelled.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.eps +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.fig +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/equil-rho_v_ns.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/postsim-typical.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-e.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-equil-rho_v_ns.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-rho_v_ns.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-tg.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r1.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r2.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r3.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/rho_v_ns.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-e.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-tg.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/results.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/5-htpb-ipdi/run.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/results.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/6-cyanate-ester/run.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/example-tutorials/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/htpolynetpackage.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/references/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/references/mol2-reference.pdf +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/references.bib +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/CURE.odg +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/bond_filter.odg +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/building-a-system.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/configs/configs-for-run.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/configuration-files.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/container-usage.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/flow1.odg +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/flow1yaml.odg +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/hydrogenated.eps +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/hydrogenated.fig +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/index.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/molecular-structure-inputs.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/periodic-networks.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/STY.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/STYCC.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/bond_filter.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/hydrogenated.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/postcure-repair.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/program-flow.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/docs/source/user-guide/usage.rst +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/scripts/check-conda-sync.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/scripts/release.sh +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/scripts/render-detail.sh +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/scripts/render-detail.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/scripts/render-snapshot.sh +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/scripts/run_all_examples.sh +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/analysis/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/analysis/analyze.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/analysis/plot.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/analysis/postsim.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/analysis/utils.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/cli.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/bondtemplate.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/configuration.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/coordinates.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/molecule.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/paramcache.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/productsplice.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/topocoord.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/core/topology.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/cure/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/cure/chain.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/cure/curecontroller.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/cure/expandreactions.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/cure/reaction.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/external/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/external/ambertools.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/external/command.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/external/gromacs.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/external/slurm.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/external/smiles_input.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/external/software.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/geometry/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/geometry/bondlist.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/geometry/lattice.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/geometry/linkcell.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/geometry/matrix4.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/geometry/placement.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/geometry/ring.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/geometry/templategeom.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/io/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/io/gro.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/io/mol2.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/io/pdb.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/repair/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/repair/cyanate_cap.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/repair/topology_surgery.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/README.md +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/claude/SKILL.md +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/example_depot/1-polystyrene.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/README.md +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/min.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/npt.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/inputs/STY.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/resources/tcl/render.tcl +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/banner.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/checkpoint.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/convergence.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/dataframetools.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/inputcheck.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/logsetup.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/profiling.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/stringthings.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/src/htpolynet/utils/vmd_viz.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/conftest.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/__init__.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/fixtures/config1.gro +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/fixtures/config1.top +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/fixtures/config2.gro +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/fixtures/config2.top +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/fixtures/items31.edr +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/fixtures/items43.edr +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/fixtures/items45.edr +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/fixtures/short.mdp +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_bondtemplate.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_cap_placement.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_chain.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_completion_bias.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_conda_sync.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_configuration.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_convergence.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_cure_site_functionality.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_dataframetools.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_density_gate.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_gpu_usability.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_gromacs_get_energy_menu.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_gromacs_gmx_energy_trace.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_inputcheck.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_linkcell_pierce.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_mdrun_gpu_options.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_mol2_bond_fallback.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_molecule_charge_report.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_moleculetype_name.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_multibody_reactions.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_paramcache.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_paramcache_ambertools.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_parameterize_react.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_placement_and_ringclose.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_plot_smoke.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_productsplice.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_projectfilesystem.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_relax_instrumentation.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_repair_charge_neutrality.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_repair_conversion.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_resources.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_ring.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_ring_pierce_figs.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_setup_claude.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_sibling_templates.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_slurm_script.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_smiles_input.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_software_provenance.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_templategeom.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_topology/test.top +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_topology.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_transrot_turn_scan.py +0 -0
- {htpolynet-2.11.3 → htpolynet-2.11.4}/tests/unit/test_user_frcmod.py +0 -0
|
@@ -7,6 +7,173 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.11.4] - 2026-09-26
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **A file of your own that replaces a packaged one now says so.** `pfs.checkout`
|
|
15
|
+
searches the user library, then the user cache, then what htpolynet ships, and took
|
|
16
|
+
the first hit silently. Overriding a packaged file is supported and often the point;
|
|
17
|
+
the trap is that a copy taken from an older version keeps that version's settings for
|
|
18
|
+
as long as it stays on the search path, and nothing said which file a run actually
|
|
19
|
+
used.
|
|
20
|
+
|
|
21
|
+
Found the hard way. A study's `npt.mdp`, copied from 2.6.2 and edited in one place,
|
|
22
|
+
stayed on its path across four upgrades. From 2.7.0 the packaged file sets
|
|
23
|
+
`lincs_order = 8`, because at `dt = 0.002` GROMACS' default of 4 is marginal --- it
|
|
24
|
+
was fatal on one chemistry in 7 of 7 builds, with exit codes 1 and 139. The stale
|
|
25
|
+
copy reverted every run to order 4, and the instability that produced was written up
|
|
26
|
+
for weeks as a property of the systems being built.
|
|
27
|
+
|
|
28
|
+
**This bears on the 2.11.3 notes below.** "Eleven of twenty builds died in the
|
|
29
|
+
anneal" is the rate from builds carrying that stale mdp, so it overstates what the
|
|
30
|
+
unrelaxed final batch alone causes. The defect and the remedy are unaffected: the
|
|
31
|
+
bond energies entering the anneal are single-point energies of the structure and owe
|
|
32
|
+
nothing to integration settings, and the paired seed test showed the settle helping
|
|
33
|
+
even at LINCS order 4. Only the headline failure rate is in doubt.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
- **A ring cure now refuses a ring that would close around an existing bond.** CURE
|
|
37
|
+
tests every candidate bond for piercing an existing ring; the ring cure has the
|
|
38
|
+
converse problem and tested nothing at all --- `ringcontroller.py` had no reference to
|
|
39
|
+
`bondtest`, `pierces_ring` or `BTRC`. A triazine could therefore form *around* a
|
|
40
|
+
monomer that was already there and thread it permanently.
|
|
41
|
+
|
|
42
|
+
That is what the stretched monomers were. Over ten finished builds, six carried a
|
|
43
|
+
threaded triazine, and the threading bonds are the same bonds found stretched past
|
|
44
|
+
2 A: 15 stretched, 13 threading, none threading without being stretched. 10 of 11
|
|
45
|
+
were pre-existing monomer backbone bonds. It explains why those bonds sit on monomers
|
|
46
|
+
that took no part in the ring, why a 160 ps anneal left them unchanged to two
|
|
47
|
+
decimals, and why they hold roughly 700 kT without being thermal --- escaping a
|
|
48
|
+
topological trap needs a bond to break, not a barrier to be crossed.
|
|
49
|
+
|
|
50
|
+
The test runs after the closure ladder and before the bonds are formed, which is
|
|
51
|
+
where the question is unambiguous: the loop is down to nearly its final size, so what
|
|
52
|
+
is inside it is what the triazine will enclose. It treats the loop as a triangle fan
|
|
53
|
+
from its centroid rather than as a plane, and images every coordinate against an
|
|
54
|
+
anchor atom, since a centroid of raw wrapped positions gives false positives across a
|
|
55
|
+
periodic boundary.
|
|
56
|
+
|
|
57
|
+
`ring_cure.prefilter_threaded_candidates` applies the same test at candidate time as
|
|
58
|
+
well, to avoid spending a ladder on a ring that is already threaded. It is **off by
|
|
59
|
+
default**, because a candidate loop is three groups a search radius apart: a formed
|
|
60
|
+
triazine's circumscribed radius is about 1.37 A and near enough rigid across 233 of
|
|
61
|
+
them, while the candidate loop encloses roughly nine times that area at a 1.0 nm
|
|
62
|
+
search radius and over twenty at 1.6 nm, which is where late iterations run.
|
|
63
|
+
Threading would carry through the shrink if nothing moved, but the ladder runs six
|
|
64
|
+
stages of NVT at 600 K, so a bond inside the candidate loop need not still be inside
|
|
65
|
+
at closure. Set `ring_cure.reject_threaded_rings: false` to reproduce the old
|
|
66
|
+
behavior entirely.
|
|
67
|
+
|
|
68
|
+
**Measured across three arms, same image, no mdp override.** Filtered builds came out
|
|
69
|
+
clean 6 of 6; unfiltered builds carried a pierced triazine in 2 of 4 --- 4, 2, 0 and 0
|
|
70
|
+
piercings, a mean of 1.5 each. There is no conversion cost: 0.971 to 0.983 in 21 to
|
|
71
|
+
23 iterations against 0.971 to 0.979 in 20 to 22 without it.
|
|
72
|
+
|
|
73
|
+
The closure-time test declined 2, 10 and 1 candidates across three builds, a mean of
|
|
74
|
+
4.3 against those 1.5 piercings. Same order of magnitude with overlapping
|
|
75
|
+
distributions, and that is as much as the data supports: at three builds against four
|
|
76
|
+
the smallest two-sided Mann-Whitney p obtainable is 0.057, so the observed 0.47 is no
|
|
77
|
+
more evidence of agreement than of excess. The two are not the same quantity either
|
|
78
|
+
--- a declined candidate is one that *would* have threaded, and the alternative
|
|
79
|
+
`select_disjoint` takes instead may itself thread and be declined in turn, so declines
|
|
80
|
+
bound the piercings prevented rather than counting them.
|
|
81
|
+
|
|
82
|
+
The candidate-time prefilter is a different matter: it discarded 1216 to 4385
|
|
83
|
+
candidates per build to catch what the closure test catches in single digits, and both
|
|
84
|
+
arms finished equally clean --- which is why it stays off by default.
|
|
85
|
+
|
|
86
|
+
### Fixed
|
|
87
|
+
|
|
88
|
+
- **A ring cure ran at constant volume from first ring to last, so it could not
|
|
89
|
+
densify.** Every ring-cure stage was NVT — the relaxation after each iteration, the
|
|
90
|
+
closure ladder, and the settle — with no constant-pressure step anywhere. Measured
|
|
91
|
+
over 22 iterations of a 233-triazine build, the box stayed at 5.241 nm to four
|
|
92
|
+
decimals and the density at 1155.9 kg/m3 from the first ring to the last, with the
|
|
93
|
+
entire volume change deferred to a single postcure NPT. CURE's density climbs
|
|
94
|
+
through its cure, roughly 1085 to 1170, because its relaxation stages run NPT above
|
|
95
|
+
Tg and are deliberately "the only above-Tg constant-pressure time in a cure".
|
|
96
|
+
|
|
97
|
+
Cure shrinkage cannot be reproduced at fixed volume by construction — Snow measures
|
|
98
|
+
0.0324 ml/g for BADCy — and a network that forms in a box which cannot respond
|
|
99
|
+
accumulates internal stress with nowhere to put it, which is a plausible route to the
|
|
100
|
+
stretched bonds recorded in `ROADMAP.md`.
|
|
101
|
+
|
|
102
|
+
`ring_cure.relax` now mirrors CURE's `relax.equilibration` exactly --- minimization,
|
|
103
|
+
NVT at 600 K, then NPT at 600 K and 1 bar --- rather than CURE's much longer
|
|
104
|
+
per-iteration equilibration. The whole sequence is above Tg, not just the
|
|
105
|
+
constant-pressure stage: relaxing at 300 K in between two 600 K closure ladders cooled
|
|
106
|
+
the network and would have put a cold, less mobile configuration under the barostat,
|
|
107
|
+
which is a good way to measure no densification and wrongly conclude the stage does
|
|
108
|
+
not work. The closure ladder itself stays constant-volume on purpose: NPT while
|
|
109
|
+
restraints are actively pulling groups together is not a stable combination.
|
|
110
|
+
|
|
111
|
+
- **A ring cure had no cold equilibration, so once it could move, its box only grew.**
|
|
112
|
+
Adding the constant-pressure relax stage above let the box respond, but `relax` ends
|
|
113
|
+
hot. Measured with relax alone over a full build, the box expands thermally for six
|
|
114
|
+
iterations to +27.9% in volume, then comes back down as the network forms: peak to
|
|
115
|
+
minimum is -7.49% in volume and +71.9 kg/m3. The two legs nearly cancel, so the net
|
|
116
|
+
is near zero and the path length is 0.4104 nm --- a frozen box captures none of it.
|
|
117
|
+
|
|
118
|
+
That descending leg is not a measurement of cure shrinkage: 2 ps at 600 K does not
|
|
119
|
+
equilibrate, so it mixes in residual thermal relaxation, and it spans conversion 0.55
|
|
120
|
+
to 0.971. It costs iterations too --- `search_radius` is an absolute length and does
|
|
121
|
+
not scale with the box, so an expanded box encloses fewer groups per sphere, and the
|
|
122
|
+
hot-only arm needed 25 iterations against 22 for the same conversion. A cure is not only shrinkage --- the hot stages enlarge
|
|
123
|
+
the box and a cold stage pulls it back, and on the pairwise route the box travels
|
|
124
|
+
three to nine times further in length than it ends up moving.
|
|
125
|
+
|
|
126
|
+
`ring_cure` now has an `equilibrate` stage identical in shape and in defaults to
|
|
127
|
+
`CURE.equilibrate` --- NPT, 300 K, 1 bar, 50000 steps of 2 fs --- run once per
|
|
128
|
+
iteration after `relax`, through the same code path the pairwise cure uses, so it
|
|
129
|
+
picks up that route's box logging and density series rather than reimplementing them.
|
|
130
|
+
The per-iteration shape of the two cures is now the same.
|
|
131
|
+
|
|
132
|
+
It is also the expensive stage, roughly 99 s against a 280 s iteration. Whether
|
|
133
|
+
100 ps is the right number for *either* route has never been measured; `ROADMAP.md`
|
|
134
|
+
sketches the study.
|
|
135
|
+
|
|
136
|
+
- **Three `ring_cure` settings could not be set at all**, because they were missing from
|
|
137
|
+
the schema, and ycleptic rejects an unknown key outright rather than ignoring it.
|
|
138
|
+
`ring_cure.relax` and `ring_cure.closure.equilibration` were never exposed, and
|
|
139
|
+
`closure.max_accept` — added in 2.11.1 — was written into `CURE`'s `drag` block by
|
|
140
|
+
mistake, where a config could set it and nothing would read it. All three now sit
|
|
141
|
+
where they belong, and a test asserts that every key the controller honors appears in
|
|
142
|
+
the schema with a matching default.
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
|
|
146
|
+
- **The installation page now says not to install `htpolynet` from conda-forge.** The
|
|
147
|
+
package published there is several releases behind and cannot currently be updated:
|
|
148
|
+
`htpolynet` depends on `ycleptic`, which is not yet available on conda-forge, so the
|
|
149
|
+
feedstock's automatic version bumps produce a package that cannot import and none has
|
|
150
|
+
been published. What is on conda-forge does install and run, so nothing warns a user
|
|
151
|
+
that they have an old `htpolynet`.
|
|
152
|
+
|
|
153
|
+
The conda-only recipe now installs Python and the MD binaries from conda-forge and
|
|
154
|
+
`htpolynet` itself from PyPI. The warning is scoped to the `htpolynet` package alone
|
|
155
|
+
--- conda-forge remains the recommended source for AmberTools and Gromacs --- and it
|
|
156
|
+
gives the two commands to check the current state rather than asking the reader to
|
|
157
|
+
trust a page that may itself be stale. The container remains the recommendation, and
|
|
158
|
+
the page now says outright that it requires no installation at all.
|
|
159
|
+
|
|
160
|
+
### Added
|
|
161
|
+
|
|
162
|
+
- **A build now says so when it hands on a bond that is not a bond any more.** At the
|
|
163
|
+
end of a ring cure and again in the final data, any bond longer than 0.2 nm is
|
|
164
|
+
reported, the worst named by atom and residue. Lengths use the minimum-image
|
|
165
|
+
convention, so a bond across a periodic boundary is not counted.
|
|
166
|
+
|
|
167
|
+
This exists because such a bond is otherwise silent: the topology is valid, every
|
|
168
|
+
molecule is neutral, and the run completes. htpolynet-study measured a C-C at 3.20 A
|
|
169
|
+
in two of five *final* structures, unchanged to two decimals by a 160 ps anneal. Ring
|
|
170
|
+
bonds always relaxed; these did not, because they are held by network tension rather
|
|
171
|
+
than by thermal motion — a monomer stretched between parts of the network that a ring
|
|
172
|
+
closure pulled apart, in a ring it was not itself part of.
|
|
173
|
+
|
|
174
|
+
This is detection and not a fix; `ROADMAP.md` has the mechanism and why no remedy has
|
|
175
|
+
been chosen. Anything computed from a structure carrying such a bond inherits it.
|
|
176
|
+
|
|
10
177
|
## [2.11.3] - 2026-09-23
|
|
11
178
|
|
|
12
179
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: htpolynet
|
|
3
|
-
Version: 2.11.
|
|
3
|
+
Version: 2.11.4
|
|
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/
|
|
@@ -199,6 +199,173 @@ Coverage as of the last measurement: **38.8%** overall.
|
|
|
199
199
|
|
|
200
200
|
## Cure and repair
|
|
201
201
|
|
|
202
|
+
- **Nobody has ever checked whether the intra-cure MD stages do anything, and they are
|
|
203
|
+
most of the cost.** Raised by Cameron 2026-09-24: the annealing and relaxation runs
|
|
204
|
+
inside a cure were chosen arbitrarily and have never been justified by a convergence
|
|
205
|
+
study. The budget, per cure iteration, from the shipped defaults:
|
|
206
|
+
|
|
207
|
+
CURE relax.equilibration 6 stages x (min + 1 ps NVT 600 + 2 ps NPT 600) 18 ps
|
|
208
|
+
equilibrate 1 x NPT 300 K, 50000 steps x 2 fs 100 ps
|
|
209
|
+
drag.equilibration disabled by default (trigger_distance 0.0) --
|
|
210
|
+
total ~118 ps
|
|
211
|
+
|
|
212
|
+
ring cure closure.equilibration 8 stages x (min + 1 ps NVT 600) 8 ps
|
|
213
|
+
relax min + 1 ps NVT 600 + 2 ps NPT 600 3 ps
|
|
214
|
+
total ~11 ps
|
|
215
|
+
|
|
216
|
+
**85% of CURE's intra-cure MD is the single 100 ps `equilibrate`**, and nothing
|
|
217
|
+
records what it accomplishes. Note also the order-of-magnitude asymmetry between the
|
|
218
|
+
two routes, which nobody chose deliberately either.
|
|
219
|
+
|
|
220
|
+
**Why it cannot be answered today.** `profiling.stage` wraps whole phases and whole
|
|
221
|
+
iterations, not individual `grompp_and_mdrun` calls, so there is no per-stage wall
|
|
222
|
+
time. And no stage records the quantity it exists to move, so "did it converge" is
|
|
223
|
+
not answerable from any existing output. One exception worth knowing: the ring
|
|
224
|
+
closure ladder already logs its max pair distance per stage at DEBUG
|
|
225
|
+
(`ringcontroller.py`, "ring-close stage"), so that ladder's convergence can be audited
|
|
226
|
+
from a run with debug logging and no new code at all.
|
|
227
|
+
|
|
228
|
+
**A study, in four parts.**
|
|
229
|
+
|
|
230
|
+
*0. Instrument.* Extend profiling to wrap each `grompp_and_mdrun` so `profile.json`
|
|
231
|
+
carries per-stage wall time, and have each stage record the observable it is supposed
|
|
232
|
+
to move: box and density against time for anything NPT (from the `.edr`, so the
|
|
233
|
+
within-stage trajectory is available and not just the endpoint), new-bond length
|
|
234
|
+
against its attenuated `b0` for `relax`, max pair distance for the ring ladder. This
|
|
235
|
+
is the only part that is repo work; it is small, and everything else depends on it.
|
|
236
|
+
|
|
237
|
+
*1. Convergence audit.* One CURE build and one ring-cure build at stock settings.
|
|
238
|
+
One data point already exists and it cuts against the cheap end of the range: 2 ps of
|
|
239
|
+
NPT per iteration does not converge a ring cure's box at all (see the constant-volume
|
|
240
|
+
entry above), so the audit should expect the answer to be tens of ps rather than
|
|
241
|
+
single digits, and should sample within a stage rather than only at its end.
|
|
242
|
+
For each stage ask a single question: at what fraction of its length does the
|
|
243
|
+
observable stop changing? A 100 ps equilibration whose density plateaus at 20 ps is
|
|
244
|
+
five times longer than it needs to be, and that is measurable once, cheaply, rather
|
|
245
|
+
than argued about.
|
|
246
|
+
|
|
247
|
+
*2. Truncation sweep.* For every stage that converges early, halve and quarter it.
|
|
248
|
+
|
|
249
|
+
*3. Null arm.* Remove the stage outright. This is the actual test of Cameron's
|
|
250
|
+
question --- a stage whose removal changes nothing downstream is not earning its
|
|
251
|
+
keep, however well it converges.
|
|
252
|
+
|
|
253
|
+
**Fix the acceptance criteria before running anything**, because every one of these
|
|
254
|
+
arms will produce a build that looks fine. Proposed: final density within a stated
|
|
255
|
+
tolerance of the stock build; conversion-against-iteration curves overlapping; no
|
|
256
|
+
increase in bonds beyond 0.2 nm as counted by `Runtime._report_overlong_bonds`; no
|
|
257
|
+
increase in postcure anneal failures across a fixed set of velocity seeds; and total
|
|
258
|
+
wall time, which is the point. Deciding those numbers afterwards is how a cheaper
|
|
259
|
+
cure gets declared equivalent because it did not obviously break.
|
|
260
|
+
|
|
261
|
+
**Who runs it.** The instrumentation is repo work. The builds are not --- example
|
|
262
|
+
builds belong to htpolynet-sweep, and a cure-physics comparison of this kind is the
|
|
263
|
+
study's kind of work. The ring-cure NPT A/B of 2026-09-24 is the first instance of
|
|
264
|
+
exactly this pattern and its design is worth copying: two arms differing in one stage
|
|
265
|
+
list, same pinned image, both arms written out explicitly so neither inherits a
|
|
266
|
+
default that might move underneath the comparison.
|
|
267
|
+
|
|
268
|
+
- **The ring cure has no cold equilibration stage, so its box cannot breathe the way
|
|
269
|
+
CURE's does.** As of 2.11.4 `ring_cure.relax` ends with NPT at 600 K, which is what
|
|
270
|
+
lets the box respond at all. CURE has that *and* a separate per-iteration
|
|
271
|
+
`equilibrate` --- NPT at 300 K for 50000 steps, 100 ps --- which the ring cure has no
|
|
272
|
+
equivalent of. So the ring cure equilibrates hot and never gets pulled back cold.
|
|
273
|
+
|
|
274
|
+
Cameron's observation is that a cure is not only shrinkage: the 600 K stages enlarge
|
|
275
|
+
the box and the 300 K equilibration pulls it back, so the box cycles every iteration.
|
|
276
|
+
htpolynet-study measured the cycle on three A2+B3 surrogates, at the cold checkpoints
|
|
277
|
+
only --- the 600 K stages log no box at all, so the real amplitude is larger:
|
|
278
|
+
|
|
279
|
+
build iters rises largest rise net path length
|
|
280
|
+
r1 17 6 +0.0120 -0.0430 0.1450
|
|
281
|
+
r2 16 5 +0.0140 -0.0420 0.1360
|
|
282
|
+
r3 16 8 +0.0260 -0.0240 0.2100
|
|
283
|
+
|
|
284
|
+
The box travels three to nine times further than it ends up moving. A ring cure over
|
|
285
|
+
22 iterations had a path length of exactly 0.0000 nm.
|
|
286
|
+
|
|
287
|
+
**Deliberately deferred, and by whom.** Presented with the choice between mirroring
|
|
288
|
+
CURE's `relax.equilibration` and mirroring its full `equilibrate`, Cameron chose the
|
|
289
|
+
cheaper one. The A/B measuring whether it suffices is what should settle this; 100 ps
|
|
290
|
+
per iteration against a 150-iteration cap is not a cost to take on speculatively.
|
|
291
|
+
|
|
292
|
+
**MEASURED 2026-09-24, and the cheap shape is not enough.** A two-arm A/B, both arms
|
|
293
|
+
on the same pinned image, differing only in the relax stage list:
|
|
294
|
+
|
|
295
|
+
arm box (nm), successive iterations rho (kg/m3) path
|
|
296
|
+
npt r1 5.5566 -> 5.6882 970 -> 904 0.1315
|
|
297
|
+
npt r2 5.5977 -> 5.6553 -> 5.6614 949 -> 917 0.0637
|
|
298
|
+
control 5.2382 / 5.2435, unchanged x3 1157 / 1154 0.0000
|
|
299
|
+
baseline 5.2405 1156.0 0.0000
|
|
300
|
+
|
|
301
|
+
The control arms are frozen to five decimals, which establishes that the constant
|
|
302
|
+
volume was the relax stage list alone and nothing else that changed between 2.11.1
|
|
303
|
+
and 2.11.4.
|
|
304
|
+
|
|
305
|
+
**Read the whole run, not its first quarter.** Over a complete 25-iteration build the
|
|
306
|
+
hot-only box has two regimes, and only the first was visible early:
|
|
307
|
+
|
|
308
|
+
iter 1 6 12 18 21 24 25
|
|
309
|
+
box 5.5977 5.7223 5.6639 5.6701 5.6442 5.5757 5.5939
|
|
310
|
+
rho 948.5 887.9 915.6 912.7 925.3 959.8 950.4
|
|
311
|
+
path 0.4104 nm, net -0.0038 nm
|
|
312
|
+
|
|
313
|
+
Thermal expansion to iteration 6, then the box comes back **down** as the network
|
|
314
|
+
forms: peak to minimum is -7.49% in volume, +71.9 kg/m3, 0.0844 ml/g. The net is
|
|
315
|
+
near zero only because the two legs nearly cancel, which is exactly why path length
|
|
316
|
+
rather than net is the statistic to quote. A frozen box captures none of it.
|
|
317
|
+
|
|
318
|
+
This retires two judgements made on the first four iterations --- mine, that a
|
|
319
|
+
still-expanding box was "differently wrong", and the reading that the climb had no
|
|
320
|
+
bound. Nor is there a conversion ceiling: the hot-only arm finished at 233 rings and
|
|
321
|
+
conversion 0.971, the same endpoint as both controls and the baseline, in 25
|
|
322
|
+
iterations against 22. The 0.09-0.10 conversion deficit at matched iteration is real
|
|
323
|
+
but is a **rate** effect worth about 14% in iterations, not a limit. Its mechanism is
|
|
324
|
+
worth keeping: ``search_radius`` is an absolute length and does not scale with the
|
|
325
|
+
box, so an expanded box encloses fewer groups per sphere and a triple is harder to
|
|
326
|
+
find.
|
|
327
|
+
|
|
328
|
+
**What the descending leg is not** is a measurement of cure shrinkage. 2 ps at 600 K
|
|
329
|
+
does not equilibrate, so that leg mixes in residual thermal relaxation, and it spans
|
|
330
|
+
conversion 0.55 to 0.971. It captures shrinkage; it does not measure it. That, and
|
|
331
|
+
Cameron's instruction to match what the binary cures already do, are what the cold
|
|
332
|
+
equilibration rests on --- not on hot-only being worse, which it is not.
|
|
333
|
+
|
|
334
|
+
What the widening actually tracks is **concentration**, which is worth knowing on its
|
|
335
|
+
own. Both arms widened for the first time at the same iteration, on the same trigger
|
|
336
|
+
of two candidates against a floor of four, from very different states: 315 unreacted
|
|
337
|
+
groups in a 192.6 nm3 box against 237 in a 143.7 nm3 box --- 1.6352 and 1.6489 groups
|
|
338
|
+
per nm3, within 0.9% of each other, while the arms sat 0.09 apart in conversion and
|
|
339
|
+
33% apart in raw count. A fixed `search_radius` makes `min_rings_per_iteration` an
|
|
340
|
+
implicit concentration criterion. Since 2.11.4 the search logs that concentration,
|
|
341
|
+
because otherwise the widening looks arbitrary in any cure whose box moves.
|
|
342
|
+
|
|
343
|
+
So a *short* cold stage will not equilibrate either, and CURE's 100 ps is the relevant
|
|
344
|
+
scale rather than an arbitrary one.
|
|
345
|
+
|
|
346
|
+
**Do not score that measurement against CURE's density curve.** CURE's 1085 -> 1170
|
|
347
|
+
is read at its *cold* checkpoints. A ring cure whose only NPT is at 600 K will sit at
|
|
348
|
+
a larger box and a lower density than its own constant-volume baseline, and that is
|
|
349
|
+
the stage working rather than failing. The signal is path length greater than zero,
|
|
350
|
+
and then the trend across hot checkpoints. If a cold stage is added later, the open
|
|
351
|
+
question is whether a short one converges at all or whether the barostat needs
|
|
352
|
+
something like CURE's 100 ps --- which is the other thing the A/B will show.
|
|
353
|
+
|
|
354
|
+
- **Properties measured before the threading filter may carry threaded rings.** The
|
|
355
|
+
filter shipped in 2.11.4; every build made before it could contain a triazine closed
|
|
356
|
+
around a monomer, which happened in 2 of 4 unfiltered builds --- 4, 2, 0 and 0
|
|
357
|
+
piercings, a mean of 1.5 each.
|
|
358
|
+
A threaded monomer is a permanent topological defect carrying a bond stretched past
|
|
359
|
+
2 A, so it is not obvious that Tg, density or modulus from those builds are unbiased,
|
|
360
|
+
and it is not obvious that they are biased either --- nobody has measured it.
|
|
361
|
+
|
|
362
|
+
The comparison is cheap now that both arms exist: build a small set with
|
|
363
|
+
`reject_threaded_rings` true and false and compare the properties, rather than
|
|
364
|
+
re-running any campaign on faith. Whoever owns a property campaign predating 2.11.4
|
|
365
|
+
should decide whether to rebuild; htpolynet-study raised this about their own and it
|
|
366
|
+
is their call, not the repo's.
|
|
367
|
+
|
|
368
|
+
|
|
202
369
|
- **A ring cure that stalls near its target has no exit but `max_iterations`.**
|
|
203
370
|
Reported by htpolynet-study 2026-09-23 from a 2.11.1 build: at conversion 0.97
|
|
204
371
|
with 24 groups left, nine iterations running (32-40) produced 77 declines and no
|
|
@@ -29,6 +29,10 @@ Installation and Prerequisites
|
|
|
29
29
|
The default image runs Gromacs on CPUs only. To use an NVIDIA GPU, use
|
|
30
30
|
the ``:cuda`` tag instead.
|
|
31
31
|
|
|
32
|
+
Nothing is installed on your system, and the image is always current ---
|
|
33
|
+
which the ``conda-forge`` package is not; see
|
|
34
|
+
:ref:`the note below <conda_forge_not_recommended>`.
|
|
35
|
+
|
|
32
36
|
See :ref:`container_usage` for the details: persistent caches, GPU setup,
|
|
33
37
|
and pinning a release.
|
|
34
38
|
|
|
@@ -153,14 +157,41 @@ On openSUSE / Fedora / RHEL:
|
|
|
153
157
|
Conda-only (simpler one-stop install)
|
|
154
158
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
155
159
|
|
|
160
|
+
.. _conda_forge_not_recommended:
|
|
161
|
+
|
|
162
|
+
.. admonition:: Do not install ``htpolynet`` itself from conda-forge
|
|
163
|
+
:class: warning
|
|
164
|
+
|
|
165
|
+
The ``htpolynet`` package on ``conda-forge`` is several releases behind
|
|
166
|
+
and is **not currently recommended**. What is published there installs
|
|
167
|
+
and runs, so nothing warns you --- you simply get an old ``htpolynet``.
|
|
168
|
+
|
|
169
|
+
It cannot be updated at the moment. ``htpolynet`` now depends on
|
|
170
|
+
`ycleptic <https://pypi.org/project/ycleptic/>`_, which is not yet
|
|
171
|
+
available on ``conda-forge``; until it is, the feedstock's automatic
|
|
172
|
+
version bumps produce a package that cannot import, so none has been
|
|
173
|
+
published.
|
|
174
|
+
|
|
175
|
+
You do not have to take this page's word for how far behind it is ---
|
|
176
|
+
the page may itself be stale by the time you read it:
|
|
177
|
+
|
|
178
|
+
.. code-block:: console
|
|
179
|
+
|
|
180
|
+
$ conda search -c conda-forge htpolynet | tail -1 # what conda-forge has
|
|
181
|
+
$ pip index versions htpolynet # what is current
|
|
182
|
+
|
|
183
|
+
This applies only to the ``htpolynet`` package. ``conda-forge`` remains
|
|
184
|
+
the recommended source for AmberTools and Gromacs, as described above.
|
|
185
|
+
|
|
156
186
|
Using Miniforge (preferred) or any other ``conda``-style installer, you
|
|
157
|
-
can manage
|
|
158
|
-
|
|
187
|
+
can manage Python and the MD binaries in a single environment, then add
|
|
188
|
+
``htpolynet`` itself from PyPI:
|
|
159
189
|
|
|
160
190
|
.. code-block:: console
|
|
161
191
|
|
|
162
|
-
$ mamba create -n htpolynet -c conda-forge python ambertools gromacs
|
|
192
|
+
$ mamba create -n htpolynet -c conda-forge python ambertools gromacs
|
|
163
193
|
$ mamba activate htpolynet
|
|
194
|
+
$ pip install htpolynet
|
|
164
195
|
|
|
165
196
|
Then install OpenBabel from your distribution's package manager as
|
|
166
197
|
described above (OpenBabel via ``conda-forge`` works too but the
|
|
@@ -472,9 +472,38 @@ def resolve_user_library(pathname, default='lib'):
|
|
|
472
472
|
return default if os.path.isdir(default) else None
|
|
473
473
|
|
|
474
474
|
|
|
475
|
+
def _note_if_shadowing(filename, source):
|
|
476
|
+
"""Says so when a file of your own replaces one htpolynet ships.
|
|
477
|
+
|
|
478
|
+
Overriding a packaged file is supported and often the point. The trap is that a
|
|
479
|
+
copy taken from an older version keeps that version's settings, silently, for as
|
|
480
|
+
long as it stays on the search path -- so a setting the packaged file has since
|
|
481
|
+
gained never reaches the run, and nothing says which file was used.
|
|
482
|
+
|
|
483
|
+
Seen 2026-09-24: an `npt.mdp` copied from 2.6.2 and edited in one place stayed on a
|
|
484
|
+
study's path across four upgrades. From 2.7.0 the packaged file sets
|
|
485
|
+
``lincs_order = 8``, because at ``dt = 0.002`` GROMACS' default of 4 is marginal and
|
|
486
|
+
was fatal on one chemistry in 7 of 7 builds. The stale copy reverted every run to
|
|
487
|
+
order 4, and the resulting instability was written up for weeks as a property of the
|
|
488
|
+
systems being built.
|
|
489
|
+
"""
|
|
490
|
+
try:
|
|
491
|
+
if _SYSTEM_LIBRARY_ and _SYSTEM_LIBRARY_._root.joinpath(filename).exists():
|
|
492
|
+
logger.warning(
|
|
493
|
+
f'{filename} was taken from your {source} and replaces the copy '
|
|
494
|
+
f'htpolynet ships. That is supported -- but if it was copied from an '
|
|
495
|
+
f'older version it still carries that version\'s settings. Compare it '
|
|
496
|
+
f'against the packaged file after any upgrade.')
|
|
497
|
+
except Exception:
|
|
498
|
+
pass
|
|
499
|
+
|
|
500
|
+
|
|
475
501
|
def checkout(filename, altpath=[]):
|
|
476
502
|
"""Copies a file to cwd; searches user library, then user cache, then system library.
|
|
477
503
|
|
|
504
|
+
A file found in the user library or cache shadows the packaged one, and
|
|
505
|
+
:func:`_note_if_shadowing` says so, because a stale copy is otherwise invisible.
|
|
506
|
+
|
|
478
507
|
Args:
|
|
479
508
|
filename (str): path relative to library root
|
|
480
509
|
altpath (list): extra search directories, defaults to []
|
|
@@ -484,8 +513,10 @@ def checkout(filename, altpath=[]):
|
|
|
484
513
|
"""
|
|
485
514
|
if _PFS_ and _PFS_.userlibrary and _PFS_.userlibrary.checkout(
|
|
486
515
|
filename, searchpath=[_PFS_.rootPath, _PFS_.projPath], altpath=altpath):
|
|
516
|
+
_note_if_shadowing(filename, 'user library')
|
|
487
517
|
return True
|
|
488
518
|
if _USER_CACHE_.checkout(filename):
|
|
519
|
+
_note_if_shadowing(filename, 'user cache')
|
|
489
520
|
return True
|
|
490
521
|
return _SYSTEM_LIBRARY_.checkout(filename)
|
|
491
522
|
|
|
@@ -14,6 +14,7 @@ from copy import deepcopy
|
|
|
14
14
|
|
|
15
15
|
import networkx as nx
|
|
16
16
|
import numpy as np
|
|
17
|
+
import pandas as pd
|
|
17
18
|
|
|
18
19
|
from networkx.algorithms import isomorphism
|
|
19
20
|
|
|
@@ -31,7 +32,7 @@ from ..cure.reaction import (Reaction, ReactionList, parse_reaction_list, extrac
|
|
|
31
32
|
is_reactant, is_ring_closing, reaction_stage)
|
|
32
33
|
from ..core.productsplice import nearer_site_atoms
|
|
33
34
|
from ..cure.ringcontroller import RingController, RingCureState
|
|
34
|
-
from ..cure.triplesearch import reactive_sites, triple_bonds_dataframe
|
|
35
|
+
from ..cure.triplesearch import bonds_by_atom, reactive_sites, triple_bonds_dataframe
|
|
35
36
|
from ..external import software as software
|
|
36
37
|
from ..external.gromacs import insert_molecules, mdp_modify, mdp_get
|
|
37
38
|
from ..external.smiles_input import materialize_smiles_inputs
|
|
@@ -694,7 +695,11 @@ class Runtime:
|
|
|
694
695
|
adf = TC.Coordinates.A
|
|
695
696
|
positions = {int(r.globalIdx): np.array([r.posX, r.posY, r.posZ])
|
|
696
697
|
for r in adf.itertuples()}
|
|
697
|
-
|
|
698
|
+
# a ring that closes around an existing bond threads that monomer through
|
|
699
|
+
# it for good; CURE refuses the mirror image of this and the ring cure did not
|
|
700
|
+
bonds_of = bonds_by_atom(TC.Topology.D['bonds'])
|
|
701
|
+
sites, chosen = rc.search(adf, positions, TC.Coordinates.box.diagonal(), resname,
|
|
702
|
+
groups, bonds_of=bonds_of)
|
|
698
703
|
if not chosen:
|
|
699
704
|
if rc.widen():
|
|
700
705
|
break
|
|
@@ -704,12 +709,17 @@ class Runtime:
|
|
|
704
709
|
work = rc.close_rings(TC, bdf, gromacs_dict=gromacs_dict)
|
|
705
710
|
# a ring the ladder could not pull shut would be bonded long and stay that way
|
|
706
711
|
bdf, chosen = rc.accept(bdf, work, chosen)
|
|
712
|
+
# now that the loop is nearly ring-sized, ask what it actually encloses
|
|
713
|
+
bdf, chosen = rc.reject_threaded(TC, bdf, chosen)
|
|
707
714
|
if not chosen:
|
|
708
715
|
rc.state.iter += 1
|
|
709
716
|
continue
|
|
710
717
|
rc.form_rings(TC, bdf, sites, chosen, template, template_resids,
|
|
711
718
|
name_translations=name_translations, atom_names=arm)
|
|
712
719
|
rc.relax(TC, gromacs_dict=gromacs_dict)
|
|
720
|
+
# the cold half of the cycle: relax ends hot and expanded, and without this
|
|
721
|
+
# the box only ever grows
|
|
722
|
+
rc.equilibrate(TC, gromacs_dict=gromacs_dict)
|
|
713
723
|
rc.record(chosen)
|
|
714
724
|
TC.write_gro(f'ring-{rc.state.iter}.gro')
|
|
715
725
|
TC.write_top(f'ring-{rc.state.iter}.top')
|
|
@@ -725,6 +735,7 @@ class Runtime:
|
|
|
725
735
|
rc.settle(TC, gromacs_dict=gromacs_dict)
|
|
726
736
|
pfs.go_proj()
|
|
727
737
|
self._report_molecule_charges('after ring cure')
|
|
738
|
+
self._report_overlong_bonds('after ring cure')
|
|
728
739
|
my_logger(f'Ring cure ends: {rc.state.rings} ring(s), conversion '
|
|
729
740
|
f'{rc.state.conversion:.3f}', logger.info)
|
|
730
741
|
return {c: os.path.basename(x) for c, x in TC.files.items() if c != 'mol2'}
|
|
@@ -845,6 +856,7 @@ class Runtime:
|
|
|
845
856
|
if dropped:
|
|
846
857
|
logger.info(f'Pruned {dropped} stale [ pairs ] entries left over from cure-induced path shortening')
|
|
847
858
|
self._report_molecule_charges(f'in {result_name}')
|
|
859
|
+
self._report_overlong_bonds(f'in {result_name}')
|
|
848
860
|
TC.write_grx_attributes(f'{result_name}.grx')
|
|
849
861
|
TC.write_gro(f'{result_name}.gro')
|
|
850
862
|
TC.write_top(f'{result_name}.top')
|
|
@@ -883,6 +895,62 @@ class Runtime:
|
|
|
883
895
|
f'moved between molecules, which parameterization does not intend.')
|
|
884
896
|
return charged
|
|
885
897
|
|
|
898
|
+
def _report_overlong_bonds(self, when, limit=0.2, show=5):
|
|
899
|
+
"""Logs any bond too long to be a bond in the structure being handed on.
|
|
900
|
+
|
|
901
|
+
A crosslinked network can finish a build carrying a bond stretched far past what
|
|
902
|
+
chemistry allows, and nothing else reports it: the topology is valid, every
|
|
903
|
+
molecule is neutral, and the run completes. htpolynet-study measured a C-C at
|
|
904
|
+
3.20 A in two of five *final* structures, unchanged to two decimals by a 160 ps
|
|
905
|
+
anneal -- a monomer held stretched by network tension from a ring closure it was
|
|
906
|
+
not part of. Ring bonds themselves always relaxed; these did not. Anything
|
|
907
|
+
computed from such a structure inherits it, so it should at least be said out
|
|
908
|
+
loud. See ROADMAP.md for the mechanism and why there is no fix yet.
|
|
909
|
+
|
|
910
|
+
Lengths use the minimum-image convention, so a bond spanning a periodic boundary
|
|
911
|
+
is measured across the boundary rather than counted as long.
|
|
912
|
+
|
|
913
|
+
Args:
|
|
914
|
+
when (str): stage label for the message, e.g. 'in final'
|
|
915
|
+
limit (float): longest credible bond, in nm. The longest ordinary single
|
|
916
|
+
bond between light elements is C-S at about 0.182 nm, so 0.2 is
|
|
917
|
+
generous: this is meant to catch a bond that is not a bond any more,
|
|
918
|
+
not to police a strained one.
|
|
919
|
+
show (int): how many of the worst to name individually
|
|
920
|
+
|
|
921
|
+
Returns:
|
|
922
|
+
pandas.DataFrame: the offending bonds, longest first
|
|
923
|
+
"""
|
|
924
|
+
TC = self.TopoCoord
|
|
925
|
+
D = getattr(getattr(TC, 'Topology', None), 'D', None) or {}
|
|
926
|
+
bonds = D.get('bonds')
|
|
927
|
+
if bonds is None or bonds.empty:
|
|
928
|
+
return pd.DataFrame()
|
|
929
|
+
work = bonds[['ai', 'aj']].copy()
|
|
930
|
+
TC.add_length_attribute(work, attr_name='length')
|
|
931
|
+
long = work[work['length'] > limit].sort_values('length', ascending=False)
|
|
932
|
+
if long.empty:
|
|
933
|
+
logger.info(f'Bond lengths {when}: no bond among {work.shape[0]} exceeds {limit} nm')
|
|
934
|
+
return long
|
|
935
|
+
A = TC.Coordinates.A.set_index('globalIdx')
|
|
936
|
+
|
|
937
|
+
def label(i):
|
|
938
|
+
try:
|
|
939
|
+
r = A.loc[int(i)]
|
|
940
|
+
return f'{r.atomName}({int(i)}) of {r.resName}{int(r.resNum)}'
|
|
941
|
+
except Exception:
|
|
942
|
+
return str(int(i))
|
|
943
|
+
|
|
944
|
+
ess = '' if long.shape[0] == 1 else 's'
|
|
945
|
+
worst = '; '.join(f'{label(r.ai)}-{label(r.aj)} at {r.length * 10:.2f} A'
|
|
946
|
+
for r in long.head(show).itertuples())
|
|
947
|
+
logger.warning(f'Bond lengths {when}: {long.shape[0]} bond{ess} of {work.shape[0]} exceed '
|
|
948
|
+
f'{limit} nm, which is longer than any real bond between these elements. '
|
|
949
|
+
f'Worst: {worst}. A bond this long survives minimization and annealing -- '
|
|
950
|
+
f'it is held by the surrounding network, not by thermal motion -- and every '
|
|
951
|
+
f'property computed from this structure carries it. See ROADMAP.md.')
|
|
952
|
+
return long
|
|
953
|
+
|
|
886
954
|
def _write_vmd_viz_files(self, result_name='final'):
|
|
887
955
|
"""Writes a PSF (real bond topology for VMD) and a TCL helper that
|
|
888
956
|
trims bonds spanning periodic boundaries so VMD doesn't render the
|