htpolynet 2.0.1__tar.gz → 2.2.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.2.0/.envrc +4 -0
- htpolynet-2.2.0/.github/workflows/conda-forge-sync.yml +56 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/.github/workflows/docker.yml +3 -2
- htpolynet-2.2.0/.github/workflows/test.yml +30 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/.gitignore +4 -2
- htpolynet-2.2.0/CHANGELOG.md +303 -0
- htpolynet-2.2.0/CITATION.cff +50 -0
- htpolynet-2.2.0/CLAUDE.md +103 -0
- htpolynet-2.2.0/PKG-INFO +127 -0
- htpolynet-2.2.0/README.md +93 -0
- htpolynet-2.2.0/ROADMAP.md +116 -0
- htpolynet-2.2.0/docker/Dockerfile +66 -0
- htpolynet-2.2.0/docker/compose.yml +13 -0
- htpolynet-2.2.0/docker/docker-entrypoint.sh +36 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/requirements.txt +1 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/conf.py +2 -2
- htpolynet-2.2.0/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +60 -0
- htpolynet-2.2.0/docs/source/example-tutorials/0-liquid-styrene/index.rst +21 -0
- htpolynet-2.2.0/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +31 -0
- htpolynet-2.2.0/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +46 -0
- htpolynet-2.2.0/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +57 -0
- htpolynet-2.2.0/docs/source/example-tutorials/0-liquid-styrene/results.rst +44 -0
- htpolynet-2.2.0/docs/source/example-tutorials/0-liquid-styrene/run.rst +46 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/configuration.rst +67 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/index.rst +24 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/introduction.rst +34 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/monomer.rst +87 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +22 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/postsim.rst +102 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/reactions.rst +90 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/results.rst +95 -0
- htpolynet-2.2.0/docs/source/example-tutorials/1-polystyrene/run.rst +92 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +95 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +24 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +32 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +23 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +127 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +163 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +105 -0
- htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +152 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +93 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +34 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +36 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +89 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +26 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses/index.rst → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +9 -6
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +122 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +91 -0
- htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +140 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +72 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +37 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +37 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +86 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +27 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +127 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +97 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +157 -0
- htpolynet-2.2.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +54 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +97 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/index.rst +45 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +67 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +149 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +17 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +154 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +204 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/results.rst +145 -0
- htpolynet-2.2.0/docs/source/example-tutorials/5-htpb-ipdi/run.rst +197 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +120 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/index.rst +51 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +75 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +120 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +23 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +163 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +146 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/results.rst +142 -0
- htpolynet-2.2.0/docs/source/example-tutorials/6-cyanate-ester/run.rst +199 -0
- htpolynet-2.2.0/docs/source/example-tutorials/index.rst +24 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/htpolynetpackage.rst +49 -9
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/index.rst +1 -0
- htpolynet-2.2.0/docs/source/install.rst +234 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/release-history.rst +1 -1
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/configs/configs-for-run.rst +17 -8
- htpolynet-2.2.0/docs/source/user-guide/container-usage.rst +268 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/index.rst +1 -0
- htpolynet-2.2.0/docs/source/user-guide/molecular-structure-inputs.rst +76 -0
- htpolynet-2.2.0/docs/source/user-guide/postcure-repair.rst +313 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/program-flow.rst +57 -9
- htpolynet-2.2.0/docs/source/user-guide/usage.rst +475 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/pyproject.toml +12 -5
- htpolynet-2.2.0/scripts/check-conda-sync.py +181 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/scripts/release.sh +52 -2
- htpolynet-2.2.0/scripts/render-detail.sh +104 -0
- htpolynet-2.2.0/scripts/render-detail.tcl +207 -0
- htpolynet-2.2.0/scripts/render-snapshot.sh +200 -0
- htpolynet-2.2.0/scripts/run_all_examples.sh +164 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/analysis/plot.py +318 -119
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/cli.py +29 -219
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/core/bondtemplate.py +69 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/core/configuration.py +2 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/core/molecule.py +27 -10
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/core/projectfilesystem.py +22 -7
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/core/runtime.py +276 -79
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/core/topocoord.py +60 -73
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/core/topology.py +74 -3
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/cure/chain.py +18 -6
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/cure/curecontroller.py +17 -15
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/cure/expandreactions.py +1 -1
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/cure/reaction.py +8 -7
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/external/ambertools.py +6 -1
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/external/command.py +5 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/external/gromacs.py +5 -3
- htpolynet-2.2.0/src/htpolynet/external/smiles_input.py +261 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/external/software.py +66 -7
- htpolynet-2.2.0/src/htpolynet/repair/__init__.py +39 -0
- htpolynet-2.2.0/src/htpolynet/repair/cyanate_cap.py +409 -0
- htpolynet-2.2.0/src/htpolynet/repair/topology_surgery.py +256 -0
- htpolynet-2.2.0/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +81 -0
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/1-polystyrene.sh → htpolynet-2.2.0/src/htpolynet/resources/example_depot/1-polystyrene.yaml +14 -49
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.sh → htpolynet-2.2.0/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +23 -76
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.sh → htpolynet-2.2.0/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +17 -67
- htpolynet-2.2.0/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +191 -0
- htpolynet-2.2.0/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +363 -0
- htpolynet-2.2.0/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +238 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/utils/banner.py +1 -1
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/utils/inputcheck.py +2 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/utils/logsetup.py +10 -4
- htpolynet-2.2.0/src/htpolynet/utils/profiling.py +219 -0
- htpolynet-2.2.0/src/htpolynet/utils/vmd_viz.py +288 -0
- htpolynet-2.2.0/tests/unit/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_chain.py +27 -16
- htpolynet-2.2.0/tests/unit/test_gpu_usability.py +77 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_gromacs_get_energy_menu.py +4 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_gromacs_gmx_energy_trace.py +4 -0
- htpolynet-2.2.0/tests/unit/test_inputcheck.py +112 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_parameterize_react.py +9 -0
- htpolynet-2.2.0/tests/unit/test_plot_smoke.py +143 -0
- htpolynet-2.2.0/tests/unit/test_resources.py +76 -0
- htpolynet-2.2.0/tests/unit/test_slurm_script.py +162 -0
- htpolynet-2.2.0/tests/unit/test_smiles_input.py +110 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_topology.py +9 -6
- htpolynet-2.0.1/CHANGELOG.md +0 -56
- htpolynet-2.0.1/Dockerfile +0 -45
- htpolynet-2.0.1/PKG-INFO +0 -78
- htpolynet-2.0.1/README.md +0 -50
- htpolynet-2.0.1/compose.yml +0 -7
- htpolynet-2.0.1/docs/source/example-tutorials/index.rst +0 -13
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/1-polystyrene/configuration.rst +0 -164
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/1-polystyrene/index.rst +0 -18
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/1-polystyrene/introduction.rst +0 -38
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/1-polystyrene/monomer.rst +0 -90
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/1-polystyrene/reactions.rst +0 -70
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/1-polystyrene/results.rst +0 -32
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/1-polystyrene/run.rst +0 -48
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/configuration.rst +0 -51
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/index.rst +0 -16
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/introduction.rst +0 -69
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/monomers.rst +0 -295
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/pics/buildtraces.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/pics/cure_info.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/pics/densification-density.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/pics/dge-pac-cured.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/pics/dge-pac-liq.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/reactions.rst +0 -104
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/results.rst +0 -46
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/run.rst +0 -267
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/configuration.rst +0 -39
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/index.rst +0 -15
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/introduction.rst +0 -68
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/pics/buildtraces.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/pics/cure_info.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/pics/densification-density.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/pics/gma-sty-cured.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/pics/gma-sty-liq.png +0 -0
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/reactions.rst +0 -275
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/results.rst +0 -46
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY/run.rst +0 -374
- htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/index.rst +0 -18
- htpolynet-2.0.1/docs/source/install.rst +0 -131
- htpolynet-2.0.1/docs/source/user-guide/container-usage.rst +0 -143
- htpolynet-2.0.1/docs/source/user-guide/molecular-structure-inputs.rst +0 -35
- htpolynet-2.0.1/docs/source/user-guide/pics/CURE.png +0 -0
- htpolynet-2.0.1/docs/source/user-guide/pics/flow1.png +0 -0
- htpolynet-2.0.1/docs/source/user-guide/usage.rst +0 -271
- htpolynet-2.0.1/src/htpolynet/resources/cfg/DGE-PAC-hi.yaml +0 -115
- htpolynet-2.0.1/src/htpolynet/resources/cfg/DGE-PAC-lo.yaml +0 -115
- htpolynet-2.0.1/src/htpolynet/resources/cfg/FDE-DFDA-hi.yaml +0 -116
- htpolynet-2.0.1/src/htpolynet/resources/cfg/FDE-DFDA-lo.yaml +0 -116
- htpolynet-2.0.1/src/htpolynet/resources/cfg/GMASTY-hi.yaml +0 -158
- htpolynet-2.0.1/src/htpolynet/resources/cfg/GMASTY-lo.yaml +0 -158
- htpolynet-2.0.1/src/htpolynet/resources/cfg/README.md +0 -1
- htpolynet-2.0.1/src/htpolynet/resources/cfg/STY.yaml +0 -23
- htpolynet-2.0.1/src/htpolynet/resources/cfg/pMSTY-hi.yaml +0 -101
- htpolynet-2.0.1/src/htpolynet/resources/cfg/pMSTY-lo.yaml +0 -101
- htpolynet-2.0.1/src/htpolynet/resources/cfg/pSTY-hi.yaml +0 -101
- htpolynet-2.0.1/src/htpolynet/resources/cfg/pSTY-lo.yaml +0 -101
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/0-liquid-styrene.sh +0 -134
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/0-liquid-styrene.tgz +0 -0
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/1-polystyrene.tgz +0 -0
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.tgz +0 -0
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.tgz +0 -0
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.sh +0 -216
- htpolynet-2.0.1/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.tgz +0 -0
- htpolynet-2.0.1/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -115
- htpolynet-2.0.1/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -91
- htpolynet-2.0.1/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -44
- htpolynet-2.0.1/tests/unit/test_resources.py +0 -24
- {htpolynet-2.0.1 → htpolynet-2.2.0}/.claude/settings.json +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/.github/workflows/release.yaml +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/.readthedocs.yaml +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/LICENSE +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/MANIFEST.in +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/Makefile +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/README.rst +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/make.bat +0 -0
- /htpolynet-2.0.1/src/htpolynet/analysis/__init__.py → /htpolynet-2.2.0/docs/source/_static/.gitkeep +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/changelog.rst +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds → htpolynet-2.2.0/docs/source/example-tutorials}/1-polystyrene/pics/STY.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds → htpolynet-2.2.0/docs/source/example-tutorials}/1-polystyrene/pics/STYCC.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds → htpolynet-2.2.0/docs/source/example-tutorials}/1-polystyrene/pics/styrene-polymerization.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/BPA.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/GMA.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/HIE.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/four_dimers.eps +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/four_dimers.fig +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/four_dimers.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/p1-traces.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/vesys.eps +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/vesys.fig +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/3-VE-STY → htpolynet-2.2.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset}/pics/vesys.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/DGE-epoxy.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/DGE-labelled.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/PAC-2d.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/PAC-labelled.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/dgesys.eps +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/dgesys.fig +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/dgesys.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/equil-rho_v_ns.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/postsim-typical.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/prod-e.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/prod-equil-rho_v_ns.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/prod-rho_v_ns.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/prod-tg.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/r1.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/r2.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/r3.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/rho_v_ns.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/short-e.png +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/postsim_analyses → htpolynet-2.2.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset}/pics/short-tg.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/references/index.rst +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/references/mol2-reference.pdf +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/references.bib +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/CURE.odg +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/bond_filter.odg +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/configuration-files.rst +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/flow1.odg +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/flow1yaml.odg +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/hydrogenated.eps +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/hydrogenated.fig +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/STY.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/STYCC.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/bond_filter.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/hydrogenated.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/__init__.py +0 -0
- {htpolynet-2.0.1/src/htpolynet/core → htpolynet-2.2.0/src/htpolynet/analysis}/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/analysis/analyze.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/analysis/postsim.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/analysis/utils.py +0 -0
- {htpolynet-2.0.1/src/htpolynet/cure → htpolynet-2.2.0/src/htpolynet/core}/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/core/coordinates.py +0 -0
- {htpolynet-2.0.1/src/htpolynet/external → htpolynet-2.2.0/src/htpolynet/cure}/__init__.py +0 -0
- {htpolynet-2.0.1/src/htpolynet/geometry → htpolynet-2.2.0/src/htpolynet/external}/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/external/slurm.py +0 -0
- {htpolynet-2.0.1/src/htpolynet/resources → htpolynet-2.2.0/src/htpolynet/geometry}/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/geometry/bondlist.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/geometry/lattice.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/geometry/linkcell.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/geometry/matrix4.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/geometry/ring.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/io/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/io/gro.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/io/mol2.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/io/pdb.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/README.md +0 -0
- {htpolynet-2.0.1/src/htpolynet/utils → htpolynet-2.2.0/src/htpolynet/resources}/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/README.md +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/min.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/npt.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/1-polystyrene/files → htpolynet-2.2.0/src/htpolynet/resources/molecules/inputs}/STY.mol2 +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/files → htpolynet-2.2.0/src/htpolynet/resources/molecules/sample-inputs}/DGE.mol2 +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
- {htpolynet-2.0.1/docs/source/example-tutorials/shortbuilds/2-DGEBA-PACM/files → htpolynet-2.2.0/src/htpolynet/resources/molecules/sample-inputs}/PAC.mol2 +0 -0
- {htpolynet-2.0.1/src/htpolynet/resources/molecules/inputs → htpolynet-2.2.0/src/htpolynet/resources/molecules/sample-inputs}/STY.mol2 +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/resources/tcl/render.tcl +0 -0
- {htpolynet-2.0.1/tests → htpolynet-2.2.0/src/htpolynet/utils}/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/utils/checkpoint.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/utils/dataframetools.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/src/htpolynet/utils/stringthings.py +0 -0
- {htpolynet-2.0.1/tests/unit → htpolynet-2.2.0/tests}/__init__.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/conftest.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/fixtures/config1.gro +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/fixtures/config1.top +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/fixtures/config2.gro +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/fixtures/config2.top +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/fixtures/items31.edr +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/fixtures/items43.edr +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/fixtures/items45.edr +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/fixtures/short.mdp +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_bondtemplate.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_configuration.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_dataframetools.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_linkcell_pierce.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_projectfilesystem.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_ring.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_ring_pierce_figs.py +0 -0
- {htpolynet-2.0.1 → htpolynet-2.2.0}/tests/unit/test_topology/test.top +0 -0
htpolynet-2.2.0/.envrc
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Check that pyproject.toml's runtime dependencies are in sync with
|
|
2
|
+
# the conda-forge feedstock's `requirements.run` block.
|
|
3
|
+
#
|
|
4
|
+
# Two modes:
|
|
5
|
+
# - Push/PR to main: warn-only. Drift adds a job-summary line so a
|
|
6
|
+
# reviewer notices but the workflow doesn't fail.
|
|
7
|
+
# - Tag push (v*): strict. Drift fails the job, so a release tag
|
|
8
|
+
# can't ship with a recipe known to be broken.
|
|
9
|
+
#
|
|
10
|
+
# The script that does the work is scripts/check-conda-sync.py; see
|
|
11
|
+
# its header for what gets compared and the PyPI→conda-forge name
|
|
12
|
+
# remap.
|
|
13
|
+
|
|
14
|
+
name: conda-forge sync check
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
push:
|
|
18
|
+
branches: [main]
|
|
19
|
+
tags: ['v*']
|
|
20
|
+
pull_request:
|
|
21
|
+
branches: [main]
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
check:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: '3.13'
|
|
33
|
+
|
|
34
|
+
- name: Run sync check
|
|
35
|
+
id: check
|
|
36
|
+
run: |
|
|
37
|
+
set +e
|
|
38
|
+
out="$(./scripts/check-conda-sync.py 2>&1)"
|
|
39
|
+
rc=$?
|
|
40
|
+
echo "$out"
|
|
41
|
+
{
|
|
42
|
+
echo '## conda-forge sync check'
|
|
43
|
+
echo ''
|
|
44
|
+
echo '```'
|
|
45
|
+
echo "$out"
|
|
46
|
+
echo '```'
|
|
47
|
+
} >> "$GITHUB_STEP_SUMMARY"
|
|
48
|
+
echo "rc=$rc" >> "$GITHUB_OUTPUT"
|
|
49
|
+
|
|
50
|
+
- name: Strict mode on tag push
|
|
51
|
+
if: startsWith(github.ref, 'refs/tags/v') && steps.check.outputs.rc != '0'
|
|
52
|
+
run: |
|
|
53
|
+
echo "::error::pyproject.toml deps drift from conda-forge recipe; release blocked."
|
|
54
|
+
echo "Either prepare the recipe update on the feedstock before tagging,"
|
|
55
|
+
echo "or plan to supersede the autotick-bot PR with a manual update."
|
|
56
|
+
exit 1
|
|
@@ -29,7 +29,8 @@ jobs:
|
|
|
29
29
|
uses: docker/build-push-action@v6
|
|
30
30
|
with:
|
|
31
31
|
context: .
|
|
32
|
+
file: docker/Dockerfile
|
|
32
33
|
push: true
|
|
33
34
|
tags: |
|
|
34
|
-
ghcr.io/
|
|
35
|
-
ghcr.io/
|
|
35
|
+
ghcr.io/cameronabrams/htpolynet:latest
|
|
36
|
+
ghcr.io/cameronabrams/htpolynet:${{ github.sha }}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
unit:
|
|
11
|
+
name: unit (py${{ matrix.python-version }})
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
# floor and current; pyproject requires-python is >=3.10
|
|
17
|
+
python-version: ['3.10', '3.13']
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
|
|
24
|
+
# Tests needing antechamber/tleap/parmchk2/gmx skip themselves when those
|
|
25
|
+
# binaries are absent, so this runner needs no MD toolchain. Everything
|
|
26
|
+
# that does not shell out still runs -- ~250 tests in a few seconds.
|
|
27
|
+
- name: Run unit tests
|
|
28
|
+
run: >
|
|
29
|
+
uv run --python ${{ matrix.python-version }} --extra test
|
|
30
|
+
pytest tests/unit -q
|
|
@@ -17,8 +17,6 @@ __pycache__/
|
|
|
17
17
|
# C extensions
|
|
18
18
|
*.so
|
|
19
19
|
|
|
20
|
-
CLAUDE.md
|
|
21
|
-
|
|
22
20
|
# Distribution / packaging
|
|
23
21
|
.Python
|
|
24
22
|
build/
|
|
@@ -105,6 +103,10 @@ ipython_config.py
|
|
|
105
103
|
# install all needed dependencies.
|
|
106
104
|
#Pipfile.lock
|
|
107
105
|
|
|
106
|
+
# uv lockfile — regenerated locally; not committed (htpolynet is a
|
|
107
|
+
# library, not a leaf application that needs a pinned dependency tree).
|
|
108
|
+
uv.lock
|
|
109
|
+
|
|
108
110
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
109
111
|
__pypackages__/
|
|
110
112
|
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to htpolynet will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [2.2.0] - 2026-08-23
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Container docs' HPC section now leads with `htpolynet gen-slurm-script`
|
|
15
|
+
instead of a hand-written batch script -- the subcommand is already
|
|
16
|
+
Apptainer-aware (`--sif`), but was documented only in `usage.rst`,
|
|
17
|
+
so container users had no reason to find it. The old example
|
|
18
|
+
defaulted to `--gres=gpu:1` and `--nv`, which is actively wrong for
|
|
19
|
+
this image (see the GPU entry under Fixed); replaced with a warning
|
|
20
|
+
explaining why CPU partitions are the right target, plus guidance on
|
|
21
|
+
sizing cores against system size and keeping the submit directory off
|
|
22
|
+
NFS.
|
|
23
|
+
- `rdkit` promoted from the `[smiles]` optional extra to a core
|
|
24
|
+
runtime dependency. Every depot example uses atom-mapped SMILES
|
|
25
|
+
(`[CH:1]`, `[NH2:2]`, etc.), so RDKit is required for any normal
|
|
26
|
+
user workflow; the obabel-only fallback that the extra was
|
|
27
|
+
guarding remains supported but isn't exercised by anything we
|
|
28
|
+
ship. `pip install htpolynet` (or `uv pip install -e .` from the
|
|
29
|
+
repo) now installs RDKit automatically; `'htpolynet[smiles]'` is
|
|
30
|
+
no longer needed (and is gone from `install.rst`).
|
|
31
|
+
- Example 5 (`5-htpb-ipdi.yaml`) retuned for shorter wall-clock.
|
|
32
|
+
The saving comes from a smaller system: the monomer pool drops
|
|
33
|
+
from 125/50/50 to 50/20/20 (IPD/DHT/THT), keeping IPD at
|
|
34
|
+
(2·DHT + 3·THT)/2 so every crosslinker still has both NCO groups
|
|
35
|
+
spoken for at full conversion. Precure anneal segments go 500 →
|
|
36
|
+
200 ps and postcure postequilibration 1000 → 200 ps.
|
|
37
|
+
Densification was re-balanced for the smaller box in the other
|
|
38
|
+
direction — `initial_density` 50 → 10 kg/m³ to give the long HTPB
|
|
39
|
+
chains room to relax without overlap, and NPT `repeat` 20 → 50 so
|
|
40
|
+
the looser start still reaches target density — so densification
|
|
41
|
+
itself does more work, on a much smaller system. The build still
|
|
42
|
+
converges.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **CI now runs the unit suite** (`.github/workflows/test.yml`), on pushes
|
|
47
|
+
to `main` and on every pull request, across Python 3.10 and 3.13. Nothing
|
|
48
|
+
ran the tests automatically before, which is how a broken import sat in
|
|
49
|
+
`test_resources.py` aborting collection indefinitely.
|
|
50
|
+
- Tests that shell out to `gmx` / `antechamber` / `tleap` / `parmchk2` now
|
|
51
|
+
skip when those binaries are absent instead of failing, so a runner with
|
|
52
|
+
no MD toolchain still reports the ~250 tests that do not need one (in
|
|
53
|
+
under 4 seconds).
|
|
54
|
+
- Test coverage for `external/slurm.py` (0% -> 98%),
|
|
55
|
+
`external/smiles_input.py` (0% -> 84%), `utils/inputcheck.py`
|
|
56
|
+
(0% -> 70%), and `analysis/plot.py` (6.7% -> 34%), none of which had
|
|
57
|
+
any. Overall coverage 34.4% -> 38.8%. The plot smoke tests were
|
|
58
|
+
checked against the pre-fix module under matplotlib 3.11 and do fail
|
|
59
|
+
there, so they would have caught the `cm.get_cmap` removal.
|
|
60
|
+
- Docker image now carries an `org.opencontainers.image.source` label,
|
|
61
|
+
linking the published GHCR package back to the repository. Without
|
|
62
|
+
it the package is orphaned: it doesn't appear on the repo page and
|
|
63
|
+
doesn't inherit repository-based access permissions.
|
|
64
|
+
- `test` optional-dependency extra (`uv run --extra test pytest tests/unit`),
|
|
65
|
+
with `dev` kept as an alias so both spellings work.
|
|
66
|
+
- `scripts/run_all_examples.sh`: fail-fast preflight that checks
|
|
67
|
+
every required native tool (`htpolynet`, `antechamber`,
|
|
68
|
+
`parmchk2`, `tleap`, `gmx`, `obabel`, `dot`) is on `PATH` before
|
|
69
|
+
starting any build. Better than hitting the first missing
|
|
70
|
+
binary hours into a partial run. Header docstring also gains a
|
|
71
|
+
Prerequisites block pointing at `install.rst` for setup.
|
|
72
|
+
- Docker image now built on `condaforge/miniforge3:latest` (was
|
|
73
|
+
`continuumio/miniconda3:latest`). Miniforge is community-
|
|
74
|
+
maintained, conda-forge only, no Anaconda Inc. terms-of-service
|
|
75
|
+
exposure. Package installs switched from `conda` to `mamba` for
|
|
76
|
+
faster solves. Verified end-to-end: built container's
|
|
77
|
+
`antechamber`, `gmx 2025.4-conda_forge`, `obabel`, `parmed`,
|
|
78
|
+
`rdkit`, and `htpolynet 2.1.0` all callable; `htpolynet
|
|
79
|
+
fetch-example 6 && htpolynet input-check` round-trips.
|
|
80
|
+
- `install.rst` rewritten around the uv + Miniforge workflow: per-
|
|
81
|
+
repo `uv venv` + `uv pip install -e .` for the Python side,
|
|
82
|
+
separate `mamba create -n gromacs` / `mamba create -n ambertools`
|
|
83
|
+
envs for the native MD binaries (both env bins appended to PATH
|
|
84
|
+
in `.bashrc`). Documents `uv tool install --editable .` as the
|
|
85
|
+
way to get a global `htpolynet` command callable from any shell.
|
|
86
|
+
Legacy conda-only one-stop install demoted to a subsection.
|
|
87
|
+
- `htpolynet.utils.profiling` (moved from `htpolynet.profiling`).
|
|
88
|
+
Small utility module — fits utils/ scope; keeps the package root
|
|
89
|
+
focused on actual subpackages. Three internal call sites
|
|
90
|
+
updated.
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
|
|
94
|
+
- **API reference documented a module that no longer exists.**
|
|
95
|
+
`docs/source/htpolynetpackage.rst` autodoc'd `htpolynet.driver`,
|
|
96
|
+
removed in the 2.0 refactor, so the package's top-level API section
|
|
97
|
+
rendered empty; it now documents `htpolynet.cli`. The same page was
|
|
98
|
+
missing nine modules that do exist -- most notably the entire
|
|
99
|
+
`repair` subpackage (`repair.cyanate_cap`, `repair.topology_surgery`,
|
|
100
|
+
i.e. the postcure-repair machinery), plus `external.slurm`,
|
|
101
|
+
`external.smiles_input`, `geometry.lattice`, `utils.profiling`, and
|
|
102
|
+
`utils.vmd_viz`. A duplicated `htpolynet.core` heading was merged.
|
|
103
|
+
- `release-history.rst` appeared in no toctree, so the pre-2.0 release
|
|
104
|
+
history (1.0.7.2 back to 0.0.1, which `CHANGELOG.md` does not cover)
|
|
105
|
+
was unreachable from the docs. Linked from `index.rst`; its 2.0.0
|
|
106
|
+
date corrected from 2026-04-15 to 2026-05-07 to match the tag.
|
|
107
|
+
- Two docstrings (`BondTemplate.matches`,
|
|
108
|
+
`utils.profiling.classify_command`) opened bullet lists with no
|
|
109
|
+
preceding blank line, which docutils rejects; both rendered as
|
|
110
|
+
errors. `conf.py` also pointed `html_static_path` at a
|
|
111
|
+
`docs/source/_static` that did not exist. The docs now build with
|
|
112
|
+
zero warnings.
|
|
113
|
+
- **The unit suite could not run at all.** `tests/unit/test_resources.py`
|
|
114
|
+
imported `RuntimeLibrary` from `htpolynet.utils.projectfilesystem` and
|
|
115
|
+
`Software` from `htpolynet.external.software`; neither symbol nor that
|
|
116
|
+
module path survived the 2.0 refactor. Because the imports were at
|
|
117
|
+
module scope, collection aborted for the *entire* `tests/unit` tree, so
|
|
118
|
+
`pytest tests/unit` had been failing outright rather than reporting
|
|
119
|
+
results. Rewritten against the current `SystemLibrary` API (15 tests).
|
|
120
|
+
- Two `test_chain.py` tests asserted exceptions (`'This is a bug - no
|
|
121
|
+
i-chain!'` / `'no j-chain!'`) that no longer exist anywhere in the
|
|
122
|
+
source: `cure/chain.py` deliberately replaced them with graceful chain
|
|
123
|
+
extension, since bonding to a chain-less atom is legitimate for
|
|
124
|
+
non-vinyl chemistry such as HTPB assembly. Rewritten to assert the
|
|
125
|
+
current semantics, plus a new test for the `create_if_missing=False`
|
|
126
|
+
branch. These had been invisible behind the collection failure above.
|
|
127
|
+
- `test_write_top` wrote its scratch file into the repository. The
|
|
128
|
+
autouse `change_test_dir` fixture chdirs each test into a directory
|
|
129
|
+
inside the source tree, and cleanup only ran on the success path, so
|
|
130
|
+
any failure or interrupt left `tests/unit/test_topology/write_test.top`
|
|
131
|
+
behind. Now uses `tempfile.TemporaryDirectory`.
|
|
132
|
+
- **Every plot call crashed on matplotlib 3.11.** `analysis/plot.py`
|
|
133
|
+
called `matplotlib.cm.get_cmap`, deprecated in 3.7 and removed in
|
|
134
|
+
3.11, at five sites. Since `pyproject.toml` floors matplotlib at
|
|
135
|
+
`>=3.5` with no ceiling, any reasonably fresh install -- including
|
|
136
|
+
the container image, which tracks latest conda-forge -- died with
|
|
137
|
+
`AttributeError: module 'matplotlib.cm' has no attribute
|
|
138
|
+
'get_cmap'` at the first density trace, i.e. *after* densification
|
|
139
|
+
had already burned its compute. Replaced with a `_get_cmap()`
|
|
140
|
+
helper that prefers the `matplotlib.colormaps` registry and falls
|
|
141
|
+
back to the legacy call only below 3.5. Caught by running example 6
|
|
142
|
+
on Picotte through the container.
|
|
143
|
+
- GPU usability is now judged on whether the gmx build can actually
|
|
144
|
+
drive the detected devices, not merely on whether its GPU support is
|
|
145
|
+
non-`disabled`. conda-forge (and hence our container) ships an
|
|
146
|
+
OpenCL Gromacs build; `gpu_ids` is populated from nvidia-smi and so
|
|
147
|
+
only ever lists NVIDIA devices, which Gromacs no longer drives via
|
|
148
|
+
OpenCL. The previous check passed that combination through, so a
|
|
149
|
+
`gpu_id` from the config reached an `mdrun` that could not honor it.
|
|
150
|
+
New `software.gpu_unusable_reasons()` centralizes the predicate and
|
|
151
|
+
is used by `_mdrun_cmd`, `_enforce_gpu_consistency`, the startup
|
|
152
|
+
banner, and the `grompp_and_mdrun` backstop, which previously
|
|
153
|
+
duplicated a weaker hardware-only version of the test.
|
|
154
|
+
- Container image was missing the `graphviz` system package, so the
|
|
155
|
+
`dot` binary `htpolynet.analysis.plot.draw_reaction_dag` shells out
|
|
156
|
+
to was absent. `pyproject.toml` declares the `graphviz` Python
|
|
157
|
+
binding but the Dockerfile only apt-installed `openbabel` and
|
|
158
|
+
`gosu`. Failure was silent-ish -- `cure/reaction.py` catches the
|
|
159
|
+
exception and logs `reaction_network.png render failed` -- so
|
|
160
|
+
container builds simply came out with no reaction-network figure.
|
|
161
|
+
Found while porting example 6 to Picotte via Apptainer.
|
|
162
|
+
- `htpolynet plots diag` parser templates: the module-path token
|
|
163
|
+
the matcher keyed on was `HTPolyNet.runtime.my_logger` /
|
|
164
|
+
`HTPolyNet.curecontroller.do_iter` from the pre-2.0 namespace.
|
|
165
|
+
After the module reorganization into `htpolynet.core.runtime` /
|
|
166
|
+
`htpolynet.cure.curecontroller`, both lines silently stopped
|
|
167
|
+
matching and the diag parser produced an empty dataframe →
|
|
168
|
+
`IndexError` at first row access. Templates refreshed to the
|
|
169
|
+
current module paths, and the module-name token dropped from
|
|
170
|
+
`pat_idx` so future renames don't break it again.
|
|
171
|
+
- Reaction-network plot (`plots/reaction_network.png`) replaced
|
|
172
|
+
with a bipartite DAG rendered via graphviz `dot` (was a
|
|
173
|
+
spring-layout networkx render that produced tangled, label-
|
|
174
|
+
overlapping diagrams; example 5 was a 30+ node hairball). Each
|
|
175
|
+
molecule is a rounded box; each reaction is a diamond with edges
|
|
176
|
+
from its reactants and an outgoing edge to its product; nodes are
|
|
177
|
+
colored by role (constituent / intermediate / final) and reaction
|
|
178
|
+
stage (param / build / cure / cap / repair). Procession-
|
|
179
|
+
expanded reactions (e.g. example 5's `polymerization` with
|
|
180
|
+
`procession.count: 15`, which `parse_reaction_list` explodes
|
|
181
|
+
into 16 sequential reactions + 15 `A18_I*` intermediates) are
|
|
182
|
+
collapsed back into one node labeled `(×N)` so the diagram
|
|
183
|
+
matches what the user wrote. New runtime dep: `graphviz` (the
|
|
184
|
+
Python wrapper; also needs the system `dot` binary, a separate
|
|
185
|
+
install).
|
|
186
|
+
|
|
187
|
+
## [2.1.0] - 2026-06-01
|
|
188
|
+
|
|
189
|
+
### Added
|
|
190
|
+
|
|
191
|
+
- New `htpolynet.repair` package implementing a postcure topology-repair stage that sits between cure and postcure. Drivers can do bond-breaking, atom deletion, atom transfer between residues, and re-templating — operations the monotonic cure/cap reaction machinery cannot perform. `repair/__init__.py` dispatches each `postcure_repair` config entry by its `type:` field; `repair/topology_surgery.py` provides the generic edit primitives (`delete_bonds` with cascading angle/dihedral/14-pair cleanup, `set_atom_attributes`, `reassign_residue`, `add_bonds_with_template` wrapping `make_bonds` + `map_from_templates` + an int-dtype rescue for atom-index columns that pandas float-promotes via NaN-tainted concat); `repair/cyanate_cap.py` carries the first concrete driver. A new `reaction_stage.repair` enum value lets repair-stage reactions ride the existing symmetry-expansion and parameterization paths so the cure-template lookup at surgery time uses a properly parameterized linked-product Molecule. The runtime gains `cfg.postcure_repair`, `Dirs.systems_repair`, and a `do_repair()` hook wired into `do_workflow` between cure and postcure, including a steepest-descent + short NVT relaxation pass to absorb LJ clashes from relocated cap atoms.
|
|
192
|
+
- New `triazine_to_cyanate_cap` repair type: the BADCy-specific driver in `repair/cyanate_cap.py`. At finite cure conversion, the topological A2+B3 BADCy model in example 6 leaves artifacts that don't exist in a real undercured thermoset — free BPA-OH groups and bare triazine C-H sites instead of -O-C#N end-groups. Atom-conservation (the count of unreacted bridge-OH atoms equals the count of dangling crosslinker C atoms across the whole system, exactly) lets the driver dismantle every incomplete triazine (`k < full_bond_count` bonded BPAs) into three independent -C#N fragments via a within-ring C-N matching; the `k` fragments already bonded to a BPA become BPA-O-C#N caps in place, and the remaining `3 - k` are transferred to the nearest unreacted BPA-OH within `cap_search_radius` (greedy matching with radius expansion + global-nearest fallback). After the surgery the heavy-atom neighbors of each deleted sacrificial H absorb its lost charge via `adjust_charges`, keeping the system net-neutral for Ewald. Topology-level outcome on the small test: 19 incomplete TAZ → 57 CYN residues + 1 surviving TAZ + exact heavy-atom conservation, with the C-N bond resolving to GAFF c1-n1 (0.115 nm sp triple) and the BPA-O-C bond to os-c1 (0.132 nm aryl-cyanate ether).
|
|
193
|
+
- Example 6 (`6-cyanate-ester.yaml`) rebuilt around the topological A2+B3 + postcure-repair architecture. The BPA-O-C#N cyanate-ester core is now represented topologically: BPA (90 → 360 at 4x scale, two reactive phenolic O atoms) reacts with bare 1,3,5-triazine TAZ (60 → 240, three reactive ring C-H atoms; ring N atoms additionally atom-mapped to N1/N2/N3 so the repair driver can refer to them by name) in a simple cure-stage aryl-ether substitution — no in-cure ring closure, no `bondcycle_collective` bypass needed because the triazine ring is pre-formed in the TAZ monomer rather than constructed via 3-way cyclotrimerization during cure. A new auxiliary CYN building block (`[CH:1]#[N:2]`, hydrogen cyanide; not inserted into the box, exists only as a parameterization template) plus a `repair`-stage `cap_with_cyanate` reaction supplies the auto-generated `BPA~O1-C1~CYN` linked-product template the repair driver splices into the system for every cap. A `postcure_repair: [{type: triazine_to_cyanate_cap, ...}]` block at the end of the YAML drives the conversion. The header comment block explains the topological model, its tradeoff vs. the previous cyclotrimerization model (no cure-kinetics realism, faithful final-network structure), and how the repair stage restores BADCy residual chemistry.
|
|
194
|
+
- New `htpolynet/profiling.py` module: a `RunProfile` with a stage-stack context manager (`profiling.stage('name')`) and a subprocess-attribution path. Every external command routed through `external/command.run` (and the two raw `subprocess.run` sites in `external/smiles_input`) is timed and classified — `gmx-mdrun`, `gmx-grompp`, `antechamber`, `parmchk2`, `tleap`, `obabel`, `rdkit`, etc. `do_workflow` wraps each stage (`setup`, `initialization`, `densification`, `precure`, `cure` with one nested frame per `iter-K`, `capping`, `postcure`, `final`) so subprocess time is attributed to whichever stage was active when the call happened. At end-of-run a formatted table is written to the log (one line per `logger.info` call, no `my_logger` asterisk padding) and a machine-readable `proj-N/profile.json` is dumped beside `final.top`.
|
|
195
|
+
- New `CURE.controls.min_bonds_per_iteration` knob (default `10`). The bond-search loop now grows the radius until at least this many bonds have been found, falling through to whatever count exists at `max_search_radius`. The effective floor is clamped against `bond_target` (remaining bonds needed to reach `desired_conversion`) and `bond_limit` (the `max_conversion_per_iteration` cap), so demanding e.g. `min_bonds_per_iteration: 50` near end-of-cure never stalls the build. The post-loop "if `nbonds > 0` proceed, else `search_failed`" branch is preserved — accepting fewer bonds than the floor (when max radius is reached) still triggers relax + equilibrate as before. Empirically on the DGEBA/PACM example, `min_bonds_per_iteration=10` cuts the cure iteration count from 41 (with `=1`) to 15; raising further to `=20` saves only one more iteration. The default of 10 was picked off that diminishing-returns curve.
|
|
196
|
+
- The "Radius increased to N nm" log line now also reports the cumulative bond count and the iteration's min-bonds floor as `(X/Y eligible bonds so far)`. Makes it visible at a glance whether the floor or `bond_target` is the active constraint as the search radius grows.
|
|
197
|
+
- `scripts/run_all_examples.sh` — runs every depot example sequentially in its own subdirectory under `./examples-runs/`. Discovers the example ID list by parsing `htpolynet fetch-example --help` (with a `0..4` fallback). Idempotent: skips `fetch-example` if a YAML is already in the per-example directory. Reports per-example exit status and exits non-zero if any example failed. Pass-through after `--` is forwarded to `htpolynet run`.
|
|
198
|
+
- `scripts/run_all_examples.sh --force-reparameterize` — convenience flag that forwards `--force-parameterization --force-checkin` to every `htpolynet run` call. Each example re-runs antechamber/parmchk/tleap on its monomers and overwrites the user cache (`~/.htpolynet/molecules/parameterized/`). Appropriate rigor when consecutive examples share monomers but differ in reaction sets — sidesteps the cache-poisoning interaction between e.g. example 0 (no reactions) and example 1 (cure reactions on STY).
|
|
199
|
+
- All five bundled examples (0–4) are now self-contained YAMLs using the RDKit atom-mapping path on each constituent, so the user names reactive atoms by chemical identity (e.g. `[CH2:1][CH3:2]`) instead of by obabel's output ordering. The legacy `.sh` and `.tgz` siblings have been removed; `htpolynet fetch-example N` now delivers a single `.yaml` for any N. Example 4 (DFDA/FDE) additionally gets a `reactive_atoms` entry for `O1`/`O2` that was missing in its prior shell script (the cap reaction references them). `htpolynet fetch-example 1` delivers the YAML directly; usage collapses to `htpolynet run 1-polystyrene.yaml`. The legacy `1-polystyrene.sh` and `1-polystyrene.tgz` have been removed. `fetch-example` now prefers `.yaml` > `.sh` > `.tgz`.
|
|
200
|
+
- Final-stage save now emits `final.viz.psf` (real bond topology, written via parmed from `final.top` + `final.gro`) and `final.viz.tcl` (drops any bond longer than 3 Å from the display) alongside the existing `final.gro` / `final.top` / `final.tpx` / `final.grx`. Load with `vmd final.viz.psf final.gro -e final.viz.tcl` to view a crosslinked network without the "long bonds across PBC" artifact. The TCL uses `topo getbondlist both` / `topo setbondlist both $list` — the valid topotools 1.x flag values are `type`, `order`, `both`, `none`; the earlier `all` returned an empty list silently and reported "PSF appears to carry no bonds". The TCL also prints the first bond's measured length so the user can verify VMD loaded coordinates in Å.
|
|
201
|
+
- New CLI subcommand `htpolynet make-viz` regenerates `final.viz.psf` + `final.viz.tcl` from any `final.top` + `final.gro` pair without re-running the full workflow. Defaults assume the current directory has `final.top` and `final.gro` (i.e. you've `cd`'d into `systems/final-results/`); override with `-top` / `-gro` / `-prefix`.
|
|
202
|
+
- VMD viz now ships a sidecar `<prefix>.viz.macros.tcl` of constituent-keyed `atomselect` macros, sourced automatically from `<prefix>.viz.tcl`. Two layers: `<NAME>` selects every atom of every instance of constituent `<NAME>` (e.g. `GMA` picks all 75 bis-GMAs in example 2; `DHT` picks all 50 linear HTPB chains in example 5), and `<NAME>_<NNN>` picks one specific instance by global molecule index. The macros are built from `final.grx`'s `molecule` / `molecule_name` columns and compress contiguous atom ranges into VMD `index A to B` tokens (so e.g. example 5's 11 KB macros file covers 225 instances). Lets a user highlight chemical entities like bis-GMA or HTPB whose internal residue scheme reflects building blocks (`BPA`+2×`HIE`, `OB`+`TB`×n+`TBO`×2) rather than the assembled molecule. The residue-level view is untouched — `resname TBO` etc. still work — the new macros are additive. `htpolynet make-viz` gains a `-grx` flag (auto-detected from the `-gro` stem) so the macros are also generated when invoked standalone.
|
|
203
|
+
- Two follow-ons to the `find_template` bystander relaxation, both needed so the small-fragment cure idiom works end-to-end:
|
|
204
|
+
- `Molecule.idx_mappers` previously asserted that the template and instance had the same bystander count on each side, and built atom-pair mappings by flat-concatenating the per-side bystander lists into one zip. With subset-bystander matching the lists can legitimately differ in length, and the flat concatenation misaligns side-A and side-B bystanders across the zip. Pair each region (bonded residues, side-A bystanders, side-B bystanders, oneaways) in its own zip so a length mismatch in one region doesn't shift the alignment of others, and drop the exact-count assertion.
|
|
205
|
+
- `map_from_templates` copies the template's angle / dihedral / pair tables into the system after mapping template atom indices through `temp2inst`. For cyanate-ester cure, the template's CY has more atoms than the post-build system's CY (the cure-reactive C consumes one H during build, so a system CY has one fewer H on that side than the fresh-from-SMILES cure-template CY does); the template's H atom that doesn't exist in the system maps to NaN. Filter rows whose mapped atom indices contain any NaN before concatenating into the system topology — those rows are force-field parameters for atoms that don't exist in the cured system. No effect on chemistries where all template atoms have system counterparts (examples 1-5).
|
|
206
|
+
- `find_template` now uses subset semantics on bystanders. A parameterization-stage template `T` matches a system-instance bond `B` if every (bystander_resname, bystander_atomname) pair declared by `T` also appears in `B`; `B` is allowed to carry additional bystanders that `T` doesn't mention. Oneaway context, atom names, residue names, and the `intraresidue` flag still require exact equality. When multiple templates match, the one with the **most** bystanders declared wins, so chain-extension templates produced by `bondchain_expand_reactions` (which carry specific bystanders) still beat the bare dimer template when their additional context is exactly the in-chain instance's. This unblocks the "small-fragment cure reactant" idiom in cases like cyanate-ester cure, where `CY.C1` is intramolecularly bonded to `BPA.O1` in every BCY-embedded instance — the bare CY+CY dimer template carries no BPA bystander, but the BPA bystander is structural context, not bond chemistry, and the subset rule lets the small template match anyway. Verified: example 1's iter-2 chain-context bond still picks the trimer chain-extension template over the bare dimer template via strict-oneaway discrimination; example 6's iter-1 CY-CY-in-BCY bond now matches the CY+CY cure template via subset-bystander relaxation.
|
|
207
|
+
- Fixed: tleap-input ordering in `external/ambertools.py` ran `check mymol` *before* `loadamberparams <frcmod>`, so any GAFF-coverage gap that parmchk2 had already patched (e.g. `h5-ce-n2` on cyanate-ester C=N–C=N dimer templates) still showed up in tleap's output as an early `Error!`. The run-wrapper's override needle then fired and aborted the parameterization, even though tleap actually completed and the `.top`/`.crd` files were valid. Reordered to load the frcmod *before* the check so the patched parameters are in scope when the molecule is validated. Unblocks new depot example 6 (cyanate-ester thermoset) whose C=N–C=N open-chain cure dimer falls in a GAFF coverage gap that parmchk2 patches by analogy. Other examples are unaffected — for chemistry where parmchk2 emits no patches, the reorder is a no-op.
|
|
208
|
+
- Fixed: cached monomer `.grx` files in `~/.htpolynet/molecules/parameterized/` carry *reactivity-related* attributes (`z`, `sea_idx`, `bondchain`, `bondchain_idx`) that are YAML-dependent — they reflect the reactions defined for the *run that wrote the cache*, not anything intrinsic to the monomer. Running example 0 (liquid styrene, no reactions) wrote `STY.grx` with all-zero z; running example 1 (polystyrene) afterward then loaded that cache and produced 0 candidate atoms in the cure bond search, silently stalling at "Radius increased to N nm (0/10 eligible bonds so far)" all the way out to the max radius. Fix: in the cache-hit branch of `_generate_molecule`, for monomers (no generator), re-run `initialize_monomer_grx_attributes()` against the current run's `zrecs` so z/sea_idx/bondchain are derived from this YAML rather than inherited from a stale cache. The cache itself can still be written with run-specific z values; only the load-time interpretation is hardened.
|
|
209
|
+
- Fixed: corollary of the monomer-cache-poisoning fix. When STY was first poisoned with z=0 by example 0, the subsequent example-1 run generated and cached the cure-stage dimer (`STY~C1-C2~STY.grx`) and the cap (`STYCC.grx`) with *empty* `bondchain` data — the dimer's `chain_manager.injest_bond` no-ops when neither atom is in a chain, which is exactly what happens when the upstream monomer's chain_manager was empty at the time. On the next example-1 run, the cached dimer loaded with 0 chains, `bondchain_expand_reactions` found no 4-atom chains to extend, and zero chain-context templates were generated — so CURE iteration 1 worked (only the dimer template was needed) but iteration 2 raised "you have a bond for which I cannot find a template" because the C1-C2 bond now had a `oneaway` STY chain partner that no available template captured. Fix: after loading a build product from cache, compare the total chain-atom count carried by the cached `chain_manager` against the sum across the product's reactants' `chain_manager`s; if the cache carries fewer atoms (either zero chains, or a partial chain — e.g. example 2's hetero-dimer `STY~C1-C2~HIE` came out length-3 instead of length-4), treat as stale, reset the molecule's `TopoCoord`/`chain_manager`/`bond_templates`/`reaction_bonds`/`sequence` to a blank state, re-parameterize via the normal `generate()` path, and overwrite the cache. The state reset is needed because the cache-load steps populate `TopoCoord` (which `generate()` will then re-merge reactants into) and the half-loaded state ends up float-promoting the `globalIdx` column on the merged dataframe, crashing the prebonding-mol2 writer. Verified on examples 1 and 2: regenerates the affected dimers, after which `bondchain_expand_reactions` produces the expected chain-extension templates (3 for example 1, 32 for example 2 — up from 12 before).
|
|
210
|
+
- New depot example `6-cyanate-ester.yaml`: bisphenol-A dicyanate ester (BADCy) thermoset. The BCY constituent is assembled at param-stage from a BPA bisphenol-A core plus two single-carbon `CY` cyanate end-groups (formaldimine, `[CH2:1]=[NH:2]` — drawn in the sp2 imino-formate active form so the cure-stage triazine-forming C-N bonds have one sacrificial H pre-allocated on each side). Mirrors example 2's `GMA = BPA + 2 HIE` build pattern. The cure stage forms C-N bonds between cyanate end-groups on different BCYs via a single `cyclize` reaction; three such bonds among three monomers close into the 1,3,5-triazine ring (the characteristic crosslink of a cured cyanate ester). The `bondcycle_collective` ring-suppression check is C-C-specific via the `ChainManager`, so the heteroatom triazine ring is allowed to close unhindered. Available as `htpolynet fetch-example 6`. Note: pair with `--force-parameterization --force-checkin` when extending the YAML to cover atoms not previously named in any reaction (e.g. CY's N1) — cached build products inherit `zrecs`-derived `z` values from the prior YAML's reactions and won't pick up newly-added reactivity otherwise.
|
|
211
|
+
- `write_top` now casts known-int columns (atom indices, function codes, dihedral periodicities, `nrexcl`, etc.) to pandas' nullable `Int64` before serialization, so they emit as e.g. `2` rather than `2.0`. The float form had been silently accepted by `gmx grompp` but rejected by `parmed`'s gromacs top reader, which broke the new `.viz.psf` generation.
|
|
212
|
+
- `gmx --version` output is now parsed for `GPU support:` (CUDA, OpenCL, SYCL, disabled) and shown alongside the version line in the startup banner.
|
|
213
|
+
- Consistency check: if the YAML config sets `mdrun_options.gpu_id` but the installed gmx was built without GPU support, or no GPU devices are visible on the host, the option is dropped and a warning is logged. This prevents the runtime crash that `gmx mdrun -gpu_id 0` produces when zero devices are detected.
|
|
214
|
+
- Cache hits during parameterization are now logged at INFO ("Using cached parameterization for `<name>`") instead of DEBUG, plus a post-loop summary line tallying reused vs freshly-parameterized molecules and a reminder of the `--force-parameterization --force-checkin` flags to invalidate stale entries. Pairs with the new "Parameterization caching" section in the user-guide.
|
|
215
|
+
- The `-restart` flag now emits a prominent runtime warning that resumption is experimental and known to fail at the first cure-stage topology update; the argparse help string is annotated likewise, and `docs/source/user-guide/usage.rst` carries an expanded warning explaining the root cause (in-memory cure state is not fully reconstructible from `cure_state.yaml` + on-disk topology files). Pre-cure stages still resume correctly; this section is parked pending a redesign of cure-state persistence.
|
|
216
|
+
- Fixed: `htpolynet run -restart` failed in `CureState.from_yaml` with a `ConstructorError` for the `!!python/object:` tag, because curecontroller's loader was `yaml.FullLoader` (which recent PyYAML tightened to reject Python object tags) while the matching `yaml.dump(self)` writes those tags. Switched to `yaml.Loader` to match what `checkpoint.py` already uses.
|
|
217
|
+
- Fixed: rebuild `self.chain_manager` from the reloaded coordinates on restart. `do_initialization` is correctly skipped by the checkpoint decorator on resume, but it's also where `chain_manager` was being constructed, so subsequent stages (`do_cure`) hit `AttributeError`. `do_workflow` now reconstructs it from the loaded TopoCoord whenever a checkpoint payload is present.
|
|
218
|
+
- Fixed: `htpolynet run -restart` could die with `shutil.SameFileError` when the userlibrary search fell through to `projPath` and the cwd already lived inside it (so the source file IS the destination). `projectfilesystem.py` now uses a `_safe_copyfile` helper that no-ops when src and dst resolve to the same path.
|
|
219
|
+
- Fixed: example 2 HIE constituent's SMILES used `[C:1]` (zero implicit H by SMILES bracket-atom rules) instead of `[CH:1]`, so the α-carbon was emitted at valence 3, antechamber typed it `c2`, and tleap failed with "no angle parameter for o - c2 - os". Documented the bracket-atom H-count gotcha in `docs/source/user-guide/molecular-structure-inputs.rst`.
|
|
220
|
+
- Fixed: the RDKit SMILES path now goes through an SDF (molfile) intermediate to obabel rather than PDB. PDB does not carry bond orders, so obabel had to re-infer them and frequently mis-assigned a carbonyl carbon as the alkene sp2 type (`C.2` from a `C-O` single bond rather than `C.2`+`O.2` double-bond pair), which propagated to GAFF as `c2` instead of `c` and broke tleap with "no angle parameter for o - c2 - os" on monomers with ester groups (e.g. HIE in example 2). SDF preserves bond orders, so obabel emits the right sybyl types and antechamber assigns the correct GAFF types.
|
|
221
|
+
- Fixed: SMILES-generated mol2 files were being written to `projPath/lib/molecules/inputs/<NAME>.mol2` because `Runtime.__init__` runs after `pfs._setup_project_dir` has `chdir`'d into the project directory. `pfs.checkout()` looks in the *user library* (`rootPath/lib/...`), so the files were unfindable and molecule generation fell through to a `BPA.pdb`/`STY.pdb` assertion. `materialize_smiles_inputs` is now invoked with an absolute `inputs_dir` rooted at the user library, and `htpolynet run` pre-creates `lib/molecules/{inputs,parameterized}/` at startup so the library is wired up even when the user's working directory had no `lib/`.
|
|
222
|
+
- Constituents in the YAML config may now carry a `smiles:` key. When present, htpolynet generates `lib/molecules/inputs/<NAME>.mol2` itself before parameterization, eliminating the obabel/sed boilerplate that example shell scripts have historically duplicated. Reactive atom names are set via either `rename_atoms: {<1-based-index>: <name>}` (obabel path, always available) or `reactive_atoms: {<smiles-map-num>: <name>}` (RDKit path, used when the SMILES contains `[*:N]` atom-mapping tokens and RDKit is importable). RDKit is an optional extra: `pip install 'htpolynet[smiles]'`; the container ships it by default.
|
|
223
|
+
|
|
224
|
+
- New `docker-entrypoint.sh` that auto-detects the host owner of the `/work` bind mount and drops privileges via `gosu` before invoking `htpolynet`. Users no longer need to set `--user`, `HOST_UID`/`HOST_GID`, or any other env vars — output files are written with host ownership automatically. The script also writes an `/etc/passwd` entry for the runtime uid so `gosu` resolves `HOME` to `/home/htpolynet` rather than falling back to `/`.
|
|
225
|
+
- Entrypoint dispatches by inspecting the first argument: if it resolves to an executable on `PATH` (`bash`, `python`, `obabel`, ...) it is exec'd directly; otherwise it is treated as an `htpolynet` subcommand. This makes it possible to run `docker compose run --rm htpolynet bash 1-polystyrene.sh --run` (i.e. drive the example shell scripts that themselves call `obabel`/`htpolynet`).
|
|
226
|
+
|
|
227
|
+
### Changed
|
|
228
|
+
|
|
229
|
+
- Docker-related files moved from the repo root into a new `docker/` subdirectory: `docker/Dockerfile`, `docker/compose.yml`, `docker/docker-entrypoint.sh`. The GH Actions build workflow and the docs `curl -O` URL are updated to match.
|
|
230
|
+
- Dockerfile installs `gosu` and uses the new entrypoint script.
|
|
231
|
+
- `compose.yml` simplified: no `user:` field; no `HOST_UID`/`HOST_GID` substitution. The entrypoint handles uid mapping at runtime.
|
|
232
|
+
- `compose.yml` bind mount uses `${PWD}:/work:Z` so SELinux-enforcing hosts (Fedora, RHEL, openSUSE Tumbleweed, ...) relabel the host directory to `container_file_t`; without this the container is denied writes regardless of POSIX permissions. Harmless on non-SELinux systems.
|
|
233
|
+
- `compose.yml` sets `MPLCONFIGDIR=/tmp/matplotlib` in the environment to silence matplotlib's "not a writable directory" warning.
|
|
234
|
+
|
|
235
|
+
### Fixed
|
|
236
|
+
|
|
237
|
+
- `_do_pap` previously applied the `_nonempty_directives` guard only to the anneal branch; preequil and postequil ran whenever the section was truthy. That broke for any YAML that defined `precure: preequilibration: ...` without an explicit `precure: postequilibration` — `_apply_runtime_defaults` injects the runtime-default postequilibration block (`ps: 0`, i.e. "no postequilibration"), `TC.equilibrate` returns `None` for `ps: 0`, and the trailing `trace('Density', edr_list, ...)` crashes with `'NoneType' object is not iterable`. Same guard now wraps all three branches, mirroring the existing anneal pattern, with a comment explaining why the postcure-default ps=0 default behaves as it does.
|
|
238
|
+
- Example 6 (postcure anneal) first cycle segment changed from `ps: 20` to `ps: 0`, matching example 3's pattern. The earlier value pushed `annealing_time[0]` to 20 ps while `init_t` was 0, tripping `gmx grompp`'s "First time point for annealing > init_t" fatal error at the postcure stage; the leading ps=0 segment exists purely to anchor the annealing protocol at simulation time 0.
|
|
239
|
+
- `Topology.rep_ex` was shifting the per-copy `resnr` by `c` (the copy index) instead of `c * residues_per_copy`, so when a multi-residue molecule (e.g. the assembled HTPB chains DHT/THT in example 5, ~41 residues each) was replicated `N` times, the resid ranges of successive copies overlapped almost completely. Single-residue monomers like IPD happened to work because `c * 1 == c`, which is why no prior example hit this. The collision surfaced downstream in `Molecule.idx_mappers` (CURE iter-1 topology update): the resid-keyed filter pulled atoms from several distinct instances at once, the atomName merge fanned out, and the same template atom got mapped to multiple instance atoms, tripping the "temp_idx N already claimed" sanity check. Fix: capture `resnr_per_copy = max(resnr)` before the concat and use it as the shift unit. Existing init.gro/init.top files with corrupted resids must be regenerated (delete `proj-*` and re-run `do_initialization`).
|
|
240
|
+
- `TopoCoord.bondcycle_collective` crashed with `AttributeError: 'NoneType' object has no attribute 'added_bonds'` when a cure bond's endpoints weren't part of any vinyl C-C bondchain (e.g. the urethane O-C linkages between TBO oxygen and IPDI formyl carbon in example 5). The chain-manager's `injest_bond` is a no-op when both atoms are outside the chain graph (and `create_if_missing=False`), so the subsequent `chain_of(r.ai)` returns `None`. Such bonds can't form a C-C bondcycle by chemistry — guard the loop and skip them.
|
|
241
|
+
- `Molecule.generate_conformers` now reuses existing conformer `.gro` files instead of regenerating them on every invocation. The check is on file presence in the cwd (`molecules/parameterized/`), so it kicks in equivalently on `-restart` and on re-runs in an existing proj dir. Changing `count` upward still triggers regeneration because the expected files won't all be present. For example 5 (HTPB chains use 6 gromacs-generated conformers per stereoisomer per long-chain monomer), this skips a substantial amount of work on every restart.
|
|
242
|
+
- Dockerfile: pre-create `/home/htpolynet` with mode `0777` so named docker volumes mounted there inherit a world-writable initial state. Without this, a fresh `htpolynet-home` volume came up owned by root and the non-root container user could not create `~/.htpolynet`, `~/.config/matplotlib`, etc.
|
|
243
|
+
- ParmEd `GromacsWarning: The [ pairs ] section contains N exceptions that aren't 1-4 pairs; make sure you know what you're doing!` at end of run. CURE can shorten the topological distance between two atoms previously templated as a 1-4 pair down to 1-3 (a new cure bond shortcuts the original 3-bond path), but nothing was pruning those now-invalid pair entries. New `Topology.prune_stale_14_pairs()` walks the bondlist and drops any `[ pairs ]` entry whose endpoints aren't actually 1-4 in the post-cure graph (uses the existing `bondlist.partners_of`, so it's O(degree³) per pair — fast). Wired into `Runtime.save_data` just before `write_top`; an INFO log line reports the count when any entries get pruned. On the DFA/FDE example 4 build (~23k pairs total) it dropped 40 stale 1-3 pairs.
|
|
244
|
+
- Silent no-op config keys in the depot example YAMLs: `initial_search_radius` (schema is `search_radius`) and `late_threshhold` (schema is `late_threshold`, no extra `h`) were being silently swallowed by `dict.get(key, default)` because the values happened to match defaults. Renamed in all four CURE-bearing examples (1, 2, 3, 4). Behavior unchanged but the docs can now quote the keys honestly.
|
|
245
|
+
- Silent no-op `nconformers:` keys on FDE and DFA in example 4. The runtime reads conformer settings from a `conformers:` sub-block (with `count`, `generator`, `minimize` keys); the flat `nconformers:` line was never read. Dropped.
|
|
246
|
+
- Default `CURE.controls.min_bonds_per_iteration` is now `10` (was effectively `1`, gated by `while nbonds == 0`). This is silent for users with custom YAMLs that don't pin the key; rerun behavior shifts toward fewer, larger CURE iterations.
|
|
247
|
+
|
|
248
|
+
### Documentation
|
|
249
|
+
|
|
250
|
+
- Container-usage page rewritten around the entrypoint-driven uid mapping; covers SELinux + `:Z` and the role of the `htpolynet-home` named volume.
|
|
251
|
+
- Full rewrite of every short-build tutorial against the current self-contained-YAML workflow. Tutorial directory names now match the depot stem: `2-DGEBA-PACM/` → `3-pacm-dgeba-epoxy-thermoset/`, `3-VE-STY/` → `2-bisgma-styrene-thermoset/`, and a brand-new tutorial 4 (`4-dfda-fde-epoxy-thermoset/`) was written. All cross-references (`ve_*` → `bgs_*`, `dgeba_*` → `pde_*`, new `dfe_*`) renamed accordingly. Each tutorial walks the YAML block-by-block via `literalinclude`, drops the obsolete `run.sh`/`obabel`/`sed` monomer-prep machinery, and points readers at the new `profile.json` and `min_bonds_per_iteration` knob where relevant. Tutorial 0's results page now ships the `final-box.png` VMD render.
|
|
252
|
+
- `scripts/run_all_examples.sh` documented in-script via its header block.
|
|
253
|
+
- Removed the legacy `src/htpolynet/resources/cfg/` directory (12 orphaned config snippets with no Python references; pre-example-depot artifacts). Updated the one `:download:` reference in `usage.rst` that pointed to a file in there.
|
|
254
|
+
|
|
255
|
+
## [2.0.1] - 2026-05-12
|
|
256
|
+
|
|
257
|
+
### Changed
|
|
258
|
+
|
|
259
|
+
- `compose.yml`: bind-mount source switched from `.` to `${PWD}` so a single shared `compose.yml` referenced via `docker compose -f` mounts the caller's working directory rather than the file's directory.
|
|
260
|
+
- `compose.yml`: `user:` field now reads `${HOST_UID}` / `${HOST_GID}` instead of `${UID}` / `${GID}` — bash's `UID` is read-only and `GID` is not exported, so the original form silently fell back to `0` (root) and broke writes into the bind mount under rootless Docker.
|
|
261
|
+
- `compose.yml`: container now gets a persistent `HOME` via a named `htpolynet-home` docker volume — without this, `~/.htpolynet` resolved to `/.htpolynet` (root of the container fs) for the non-root user and the user cache could not be created. The named volume also keeps parameterized monomers/oligomers around across `docker compose run --rm` invocations.
|
|
262
|
+
|
|
263
|
+
### Fixed
|
|
264
|
+
|
|
265
|
+
- Dockerfile header comments: removed duplicated `htpolynet` token in the example `docker run` invocations (the `ENTRYPOINT` already provides it) and added `--user $(id -u):$(id -g)` so output files are not owned by root.
|
|
266
|
+
|
|
267
|
+
### Documentation
|
|
268
|
+
|
|
269
|
+
- Container-usage page now notes that the image is published only to GHCR (a bare `docker run htpolynet` resolves against Docker Hub and fails) and shows a `docker tag` shortcut for a local alias.
|
|
270
|
+
- Added a `curl -O` one-liner for fetching `compose.yml` directly from the repo.
|
|
271
|
+
|
|
272
|
+
## [2.0.0] - 2026-05-07
|
|
273
|
+
|
|
274
|
+
### Changed
|
|
275
|
+
|
|
276
|
+
- Package renamed from `HTPolyNet` to `htpolynet` (fully lowercase) for PEP 8 compliance and PyPI consistency.
|
|
277
|
+
- Runtime now logs the HTPolyNet git commit hash at startup, with a warning when uncommitted changes are present.
|
|
278
|
+
|
|
279
|
+
### Added
|
|
280
|
+
|
|
281
|
+
- Apptainer/Singularity container support: distributed as a `.sif` image for reproducible execution on HPC clusters.
|
|
282
|
+
- New `gen-slurm-script` subcommand generates a ready-to-submit SLURM batch script from an htpolynet YAML config file.
|
|
283
|
+
|
|
284
|
+
### Fixed
|
|
285
|
+
|
|
286
|
+
- Chain-expansion bug: bond-chain `ChainManager` was not rebuilt for monomers on the fetch path, causing `bondchain_expand_reactions` to produce no chain-extended oligomers in runs that reused cached parameterizations.
|
|
287
|
+
|
|
288
|
+
## [1.0.9] - 2025-01-01
|
|
289
|
+
|
|
290
|
+
### Added
|
|
291
|
+
|
|
292
|
+
- `minimum_bondcycle_length` parameter to allow for cyclic polymerization above a certain threshold length.
|
|
293
|
+
|
|
294
|
+
### Fixed
|
|
295
|
+
|
|
296
|
+
- Rings not transferred from monomer templates if they are pre-parameterized.
|
|
297
|
+
- Atom indexes in bondchain structure not remapped after atom deletion.
|
|
298
|
+
|
|
299
|
+
## [1.0.8] - 2024-01-04
|
|
300
|
+
|
|
301
|
+
### Changed
|
|
302
|
+
|
|
303
|
+
- Uses `chordless_cycles` to find rings; `ringidx` is no longer a unique atom attribute; improved ring-pierce detection.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: >-
|
|
3
|
+
If you use htpolynet in published work, please cite the SoftwareX article
|
|
4
|
+
under `preferred-citation`, along with the GAFF and Gromacs papers listed
|
|
5
|
+
in the documentation.
|
|
6
|
+
title: htpolynet
|
|
7
|
+
abstract: >-
|
|
8
|
+
Automated molecular-dynamics system builder for amorphous network polymers.
|
|
9
|
+
Generates atomistic models of cross-linked polymer networks, together with
|
|
10
|
+
the Gromacs topology and parameter files needed to simulate them, from only
|
|
11
|
+
the monomer structures, a description of the polymerization chemistry, and a
|
|
12
|
+
handful of system-size and composition options. Atom typing and parameter
|
|
13
|
+
generation use the General Amber Force Field.
|
|
14
|
+
type: software
|
|
15
|
+
authors:
|
|
16
|
+
- family-names: Abrams
|
|
17
|
+
given-names: Cameron F.
|
|
18
|
+
email: cfa22@drexel.edu
|
|
19
|
+
affiliation: Drexel University
|
|
20
|
+
repository-code: https://github.com/cameronabrams/htpolynet
|
|
21
|
+
url: https://htpolynet.readthedocs.io/
|
|
22
|
+
license: MIT
|
|
23
|
+
version: 2.1.0
|
|
24
|
+
date-released: '2026-06-01'
|
|
25
|
+
keywords:
|
|
26
|
+
- molecular dynamics
|
|
27
|
+
- crosslinked polymers
|
|
28
|
+
- thermosets
|
|
29
|
+
- polymer networks
|
|
30
|
+
- Gromacs
|
|
31
|
+
- GAFF
|
|
32
|
+
preferred-citation:
|
|
33
|
+
type: article
|
|
34
|
+
title: >-
|
|
35
|
+
HTPolyNet: A general system generator for all-atom molecular simulations of
|
|
36
|
+
amorphous crosslinked polymers
|
|
37
|
+
authors:
|
|
38
|
+
- family-names: Huang
|
|
39
|
+
given-names: Ming
|
|
40
|
+
- family-names: Abrams
|
|
41
|
+
given-names: Cameron F.
|
|
42
|
+
email: cfa22@drexel.edu
|
|
43
|
+
affiliation: Drexel University
|
|
44
|
+
journal: SoftwareX
|
|
45
|
+
volume: 21
|
|
46
|
+
start: 101303
|
|
47
|
+
year: 2023
|
|
48
|
+
month: 2
|
|
49
|
+
issn: 2352-7110
|
|
50
|
+
doi: 10.1016/j.softx.2022.101303
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Working on htpolynet
|
|
2
|
+
|
|
3
|
+
## Roadmap and changelog
|
|
4
|
+
|
|
5
|
+
`ROADMAP.md` holds upgrades we have identified but not done. `CHANGELOG.md`
|
|
6
|
+
holds what shipped, in Keep-a-Changelog form with a live `[Unreleased]`
|
|
7
|
+
section.
|
|
8
|
+
|
|
9
|
+
Keep both current as a matter of course, without being asked:
|
|
10
|
+
|
|
11
|
+
- When we decide *not* to do something now — a deferred fix, an idea worth
|
|
12
|
+
keeping, a limitation we chose to live with — add it to `ROADMAP.md` with
|
|
13
|
+
enough context to act on it months later. An entry that just says "make
|
|
14
|
+
Gromacs faster" is worthless; say which build, why it is slow, and what
|
|
15
|
+
the tradeoff is.
|
|
16
|
+
- When a roadmap item ships, delete it from `ROADMAP.md` and describe it in
|
|
17
|
+
`CHANGELOG.md` under `[Unreleased]`.
|
|
18
|
+
- Surface relevant roadmap items unprompted when we touch related code.
|
|
19
|
+
|
|
20
|
+
## Running the tests
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
uv run --extra test pytest tests/unit -q
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`dev` is an alias for the `test` extra; both work.
|
|
27
|
+
|
|
28
|
+
Three test modules shell out to external binaries — `test_parameterize_react`
|
|
29
|
+
needs antechamber/parmchk2/tleap/gmx, and the two `test_gromacs_*` modules
|
|
30
|
+
need gmx. They skip when those are absent rather than failing, which is what
|
|
31
|
+
lets CI run on a plain runner. With the tool chain present the suite takes a
|
|
32
|
+
couple of minutes; without it, about four seconds.
|
|
33
|
+
|
|
34
|
+
## The test suite runs inside the source tree
|
|
35
|
+
|
|
36
|
+
`tests/conftest.py` has an autouse `change_test_dir` fixture that chdirs each
|
|
37
|
+
test into `tests/unit/<module_name>/` if that directory exists, otherwise
|
|
38
|
+
`tests/unit/`. Both are inside the repo. So a test that writes a file to the
|
|
39
|
+
working directory litters the source tree, and cleanup that runs only on the
|
|
40
|
+
success path leaves the file behind whenever the test fails or is
|
|
41
|
+
interrupted. Write scratch files to `tmp_path` or a
|
|
42
|
+
`tempfile.TemporaryDirectory` instead.
|
|
43
|
+
|
|
44
|
+
## Docs must build with zero warnings
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
uv run --with-requirements docs/requirements.txt --with sphinx \
|
|
48
|
+
python -m sphinx -b html docs/source /tmp/docbuild
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
It currently builds clean; keep it that way. Two things that historically
|
|
52
|
+
broke it:
|
|
53
|
+
|
|
54
|
+
- `docs/source/htpolynetpackage.rst` is a hand-maintained list of
|
|
55
|
+
`automodule` directives, so it drifts silently as modules are added,
|
|
56
|
+
moved, or deleted. It once autodoc'd `htpolynet.driver` for months after
|
|
57
|
+
that module ceased to exist. When you add or move a module, add it here.
|
|
58
|
+
- Adding a module to that page renders its docstrings for the first time,
|
|
59
|
+
which surfaces latent RST errors. The usual one is a bullet list with no
|
|
60
|
+
blank line before it, which docutils rejects.
|
|
61
|
+
|
|
62
|
+
## Releases
|
|
63
|
+
|
|
64
|
+
Use `scripts/release.sh <version>`. It rotates `[Unreleased]` into a dated
|
|
65
|
+
section, bumps the version in `pyproject.toml`, commits, tags, and pushes.
|
|
66
|
+
Pushing the tag is what triggers publication: `release.yaml` builds and
|
|
67
|
+
publishes to PyPI, creates a GitHub Release from the changelog notes, and
|
|
68
|
+
kicks a Read the Docs build. The conda-forge autotick bot then opens a
|
|
69
|
+
feedstock PR.
|
|
70
|
+
|
|
71
|
+
Do not hand-roll any of that. The script's preflight also checks that
|
|
72
|
+
`pyproject.toml`'s runtime dependencies still match the conda-forge feedstock
|
|
73
|
+
recipe — the autotick bot only bumps version and sha, so a dependency change
|
|
74
|
+
we forget to mirror ships a broken conda package.
|
|
75
|
+
|
|
76
|
+
Because the changelog notes become the public release body, keep
|
|
77
|
+
`[Unreleased]` free of internal bookkeeping ("got bundled into commit
|
|
78
|
+
abc1234") and file entries under the right heading.
|
|
79
|
+
|
|
80
|
+
## The container
|
|
81
|
+
|
|
82
|
+
The image is `ghcr.io/cameronabrams/htpolynet`, built by `docker.yml` from
|
|
83
|
+
`docker/Dockerfile`. It rebuilds weekly on a schedule and on any tag matching
|
|
84
|
+
`v*` or `d*`. A `d*` tag is the way to rebuild the image without cutting a
|
|
85
|
+
release — useful when only the Dockerfile changed.
|
|
86
|
+
|
|
87
|
+
Its Gromacs comes from conda-forge, which means **OpenCL, not CUDA**, and
|
|
88
|
+
generic `AVX2_256` SIMD. Gromacs no longer drives NVIDIA devices through
|
|
89
|
+
OpenCL, so the image cannot use a GPU: on a cluster, target CPU partitions
|
|
90
|
+
and do not request `--gres=gpu` or pass `--nv`. See `ROADMAP.md`.
|
|
91
|
+
|
|
92
|
+
## Two invariants worth not breaking
|
|
93
|
+
|
|
94
|
+
- **Colormaps go through `analysis.plot._get_cmap()`**, never
|
|
95
|
+
`matplotlib.cm.get_cmap` directly. The latter was removed in matplotlib
|
|
96
|
+
3.11, and since `pyproject.toml` floors matplotlib without a ceiling, a
|
|
97
|
+
direct call breaks every plot on a fresh install — after densification has
|
|
98
|
+
already spent its compute.
|
|
99
|
+
- **GPU usability is decided by `external.software.gpu_unusable_reasons()`**,
|
|
100
|
+
which is the single place that reconciles detected hardware against what
|
|
101
|
+
the gmx build can actually drive. Do not add ad-hoc `if gpu_ids:` checks
|
|
102
|
+
elsewhere; a weaker hardware-only duplicate of this test used to live in
|
|
103
|
+
`grompp_and_mdrun` and disagreed with it.
|