htpolynet 2.1.0__tar.gz → 2.3.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.
Files changed (347) hide show
  1. htpolynet-2.3.0/.claude/skills/htpolynet/SKILL.md +71 -0
  2. htpolynet-2.3.0/.github/workflows/conda-forge-sync.yml +56 -0
  3. {htpolynet-2.1.0 → htpolynet-2.3.0}/.github/workflows/docker.yml +2 -2
  4. htpolynet-2.3.0/.github/workflows/test.yml +30 -0
  5. {htpolynet-2.1.0 → htpolynet-2.3.0}/.gitignore +4 -2
  6. {htpolynet-2.1.0 → htpolynet-2.3.0}/CHANGELOG.md +269 -0
  7. htpolynet-2.3.0/CITATION.cff +56 -0
  8. htpolynet-2.3.0/CLAUDE.md +103 -0
  9. {htpolynet-2.1.0 → htpolynet-2.3.0}/PKG-INFO +45 -15
  10. htpolynet-2.3.0/README.md +94 -0
  11. htpolynet-2.3.0/ROADMAP.md +255 -0
  12. {htpolynet-2.1.0 → htpolynet-2.3.0}/docker/Dockerfile +13 -7
  13. {htpolynet-2.1.0 → htpolynet-2.3.0}/docker/compose.yml +1 -1
  14. htpolynet-2.3.0/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
  15. htpolynet-2.3.0/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
  16. htpolynet-2.3.0/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
  17. htpolynet-2.3.0/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
  18. htpolynet-2.3.0/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +22 -0
  19. htpolynet-2.3.0/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
  20. htpolynet-2.3.0/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
  21. htpolynet-2.3.0/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
  22. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/results.rst +31 -0
  23. htpolynet-2.3.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
  24. htpolynet-2.3.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
  25. htpolynet-2.3.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
  26. htpolynet-2.3.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +23 -0
  27. htpolynet-2.3.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
  28. htpolynet-2.3.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
  29. htpolynet-2.3.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
  30. htpolynet-2.3.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
  31. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +18 -9
  32. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +13 -12
  33. htpolynet-2.3.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
  34. htpolynet-2.3.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
  35. htpolynet-2.3.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
  36. htpolynet-2.3.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +26 -0
  37. htpolynet-2.3.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
  38. htpolynet-2.3.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
  39. htpolynet-2.3.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
  40. htpolynet-2.3.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
  41. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +1 -1
  42. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +15 -4
  43. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +12 -11
  44. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
  45. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
  46. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
  47. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +27 -0
  48. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
  49. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
  50. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
  51. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
  52. htpolynet-2.3.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +157 -0
  53. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +97 -0
  54. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/index.rst +45 -0
  55. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +67 -0
  56. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +149 -0
  57. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
  58. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
  59. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
  60. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +17 -0
  61. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
  62. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
  63. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
  64. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
  65. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +154 -0
  66. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +204 -0
  67. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/results.rst +145 -0
  68. htpolynet-2.3.0/docs/source/example-tutorials/5-htpb-ipdi/run.rst +197 -0
  69. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +120 -0
  70. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/index.rst +51 -0
  71. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +75 -0
  72. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +120 -0
  73. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +23 -0
  74. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
  75. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
  76. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
  77. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
  78. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
  79. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
  80. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
  81. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +163 -0
  82. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +146 -0
  83. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/results.rst +142 -0
  84. htpolynet-2.3.0/docs/source/example-tutorials/6-cyanate-ester/run.rst +199 -0
  85. htpolynet-2.3.0/docs/source/example-tutorials/index.rst +24 -0
  86. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/htpolynetpackage.rst +54 -9
  87. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/index.rst +1 -0
  88. htpolynet-2.3.0/docs/source/install.rst +234 -0
  89. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/release-history.rst +1 -1
  90. htpolynet-2.3.0/docs/source/user-guide/building-a-system.rst +172 -0
  91. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/configs/configs-for-run.rst +7 -1
  92. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/container-usage.rst +70 -17
  93. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/index.rst +2 -0
  94. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/molecular-structure-inputs.rst +1 -1
  95. htpolynet-2.3.0/docs/source/user-guide/postcure-repair.rst +313 -0
  96. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/usage.rst +45 -9
  97. {htpolynet-2.1.0 → htpolynet-2.3.0}/pyproject.toml +9 -5
  98. htpolynet-2.3.0/scripts/check-conda-sync.py +181 -0
  99. {htpolynet-2.1.0 → htpolynet-2.3.0}/scripts/release.sh +52 -2
  100. htpolynet-2.3.0/scripts/render-detail.sh +104 -0
  101. htpolynet-2.3.0/scripts/render-detail.tcl +207 -0
  102. htpolynet-2.3.0/scripts/render-snapshot.sh +200 -0
  103. {htpolynet-2.1.0 → htpolynet-2.3.0}/scripts/run_all_examples.sh +20 -3
  104. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/analysis/plot.py +318 -119
  105. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/cli.py +1 -1
  106. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/core/bondtemplate.py +2 -0
  107. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/core/molecule.py +7 -0
  108. htpolynet-2.3.0/src/htpolynet/core/paramcache.py +132 -0
  109. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/core/projectfilesystem.py +1 -1
  110. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/core/runtime.py +156 -56
  111. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/cure/curecontroller.py +1 -1
  112. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/cure/reaction.py +7 -7
  113. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/external/ambertools.py +23 -4
  114. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/external/command.py +1 -1
  115. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/external/gromacs.py +5 -3
  116. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/external/smiles_input.py +7 -5
  117. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/external/software.py +39 -13
  118. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/example_depot/1-polystyrene.yaml +2 -2
  119. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +10 -10
  120. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/utils/banner.py +1 -1
  121. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/utils/logsetup.py +10 -4
  122. {htpolynet-2.1.0/src/htpolynet → htpolynet-2.3.0/src/htpolynet/utils}/profiling.py +1 -0
  123. htpolynet-2.3.0/tests/unit/__init__.py +0 -0
  124. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_chain.py +27 -16
  125. htpolynet-2.3.0/tests/unit/test_gpu_usability.py +77 -0
  126. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_gromacs_get_energy_menu.py +4 -0
  127. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_gromacs_gmx_energy_trace.py +4 -0
  128. htpolynet-2.3.0/tests/unit/test_inputcheck.py +112 -0
  129. htpolynet-2.3.0/tests/unit/test_paramcache.py +326 -0
  130. htpolynet-2.3.0/tests/unit/test_paramcache_ambertools.py +198 -0
  131. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_parameterize_react.py +9 -0
  132. htpolynet-2.3.0/tests/unit/test_plot_smoke.py +143 -0
  133. htpolynet-2.3.0/tests/unit/test_resources.py +76 -0
  134. htpolynet-2.3.0/tests/unit/test_slurm_script.py +162 -0
  135. htpolynet-2.3.0/tests/unit/test_smiles_input.py +110 -0
  136. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_topology.py +9 -6
  137. htpolynet-2.1.0/README.md +0 -66
  138. htpolynet-2.1.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
  139. htpolynet-2.1.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
  140. htpolynet-2.1.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
  141. htpolynet-2.1.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
  142. htpolynet-2.1.0/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
  143. htpolynet-2.1.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
  144. htpolynet-2.1.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
  145. htpolynet-2.1.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
  146. htpolynet-2.1.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
  147. htpolynet-2.1.0/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
  148. htpolynet-2.1.0/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +0 -58
  149. htpolynet-2.1.0/docs/source/example-tutorials/index.rst +0 -22
  150. htpolynet-2.1.0/docs/source/install.rst +0 -137
  151. htpolynet-2.1.0/tests/unit/test_resources.py +0 -24
  152. {htpolynet-2.1.0 → htpolynet-2.3.0}/.claude/settings.json +0 -0
  153. {htpolynet-2.1.0 → htpolynet-2.3.0}/.envrc +0 -0
  154. {htpolynet-2.1.0 → htpolynet-2.3.0}/.github/workflows/release.yaml +0 -0
  155. {htpolynet-2.1.0 → htpolynet-2.3.0}/.readthedocs.yaml +0 -0
  156. {htpolynet-2.1.0 → htpolynet-2.3.0}/LICENSE +0 -0
  157. {htpolynet-2.1.0 → htpolynet-2.3.0}/MANIFEST.in +0 -0
  158. {htpolynet-2.1.0 → htpolynet-2.3.0}/docker/docker-entrypoint.sh +0 -0
  159. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/Makefile +0 -0
  160. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/README.rst +0 -0
  161. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/make.bat +0 -0
  162. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/requirements.txt +0 -0
  163. /htpolynet-2.1.0/src/htpolynet/analysis/__init__.py → /htpolynet-2.3.0/docs/source/_static/.gitkeep +0 -0
  164. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/changelog.rst +0 -0
  165. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/conf.py +0 -0
  166. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +0 -0
  167. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/0-liquid-styrene/index.rst +0 -0
  168. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +0 -0
  169. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +0 -0
  170. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +0 -0
  171. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/0-liquid-styrene/results.rst +0 -0
  172. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/0-liquid-styrene/run.rst +0 -0
  173. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/configuration.rst +0 -0
  174. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/index.rst +0 -0
  175. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/introduction.rst +0 -0
  176. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/monomer.rst +0 -0
  177. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/pics/STY.png +0 -0
  178. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/pics/STYCC.png +0 -0
  179. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
  180. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/pics/styrene-polymerization.png +0 -0
  181. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/postsim.rst +0 -0
  182. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/reactions.rst +0 -0
  183. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/1-polystyrene/run.rst +0 -0
  184. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +0 -0
  185. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +0 -0
  186. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +0 -0
  187. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/BPA.png +0 -0
  188. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/GMA.png +0 -0
  189. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/HIE.png +0 -0
  190. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.eps +0 -0
  191. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.fig +0 -0
  192. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.png +0 -0
  193. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/p1-traces.png +0 -0
  194. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.eps +0 -0
  195. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.fig +0 -0
  196. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.png +0 -0
  197. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +0 -0
  198. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +0 -0
  199. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +0 -0
  200. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +0 -0
  201. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +0 -0
  202. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +0 -0
  203. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-epoxy.png +0 -0
  204. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-labelled.png +0 -0
  205. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-2d.png +0 -0
  206. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-labelled.png +0 -0
  207. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.eps +0 -0
  208. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.fig +0 -0
  209. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.png +0 -0
  210. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/equil-rho_v_ns.png +0 -0
  211. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/postsim-typical.png +0 -0
  212. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-e.png +0 -0
  213. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-equil-rho_v_ns.png +0 -0
  214. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-rho_v_ns.png +0 -0
  215. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-tg.png +0 -0
  216. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r1.png +0 -0
  217. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r2.png +0 -0
  218. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r3.png +0 -0
  219. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/rho_v_ns.png +0 -0
  220. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-e.png +0 -0
  221. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-tg.png +0 -0
  222. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +0 -0
  223. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +0 -0
  224. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +0 -0
  225. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +0 -0
  226. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +0 -0
  227. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +0 -0
  228. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +0 -0
  229. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +0 -0
  230. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/references/index.rst +0 -0
  231. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/references/mol2-reference.pdf +0 -0
  232. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/references.bib +0 -0
  233. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/CURE.odg +0 -0
  234. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/bond_filter.odg +0 -0
  235. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
  236. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
  237. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/configuration-files.rst +0 -0
  238. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/flow1.odg +0 -0
  239. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/flow1yaml.odg +0 -0
  240. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/hydrogenated.eps +0 -0
  241. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/hydrogenated.fig +0 -0
  242. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/STY.png +0 -0
  243. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/STYCC.png +0 -0
  244. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
  245. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/bond_filter.png +0 -0
  246. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
  247. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
  248. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/hydrogenated.png +0 -0
  249. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
  250. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
  251. {htpolynet-2.1.0 → htpolynet-2.3.0}/docs/source/user-guide/program-flow.rst +0 -0
  252. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/__init__.py +0 -0
  253. {htpolynet-2.1.0/src/htpolynet/core → htpolynet-2.3.0/src/htpolynet/analysis}/__init__.py +0 -0
  254. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/analysis/analyze.py +0 -0
  255. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/analysis/postsim.py +0 -0
  256. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/analysis/utils.py +0 -0
  257. {htpolynet-2.1.0/src/htpolynet/cure → htpolynet-2.3.0/src/htpolynet/core}/__init__.py +0 -0
  258. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/core/configuration.py +0 -0
  259. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/core/coordinates.py +0 -0
  260. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/core/topocoord.py +0 -0
  261. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/core/topology.py +0 -0
  262. {htpolynet-2.1.0/src/htpolynet/external → htpolynet-2.3.0/src/htpolynet/cure}/__init__.py +0 -0
  263. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/cure/chain.py +0 -0
  264. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/cure/expandreactions.py +0 -0
  265. {htpolynet-2.1.0/src/htpolynet/geometry → htpolynet-2.3.0/src/htpolynet/external}/__init__.py +0 -0
  266. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/external/slurm.py +0 -0
  267. {htpolynet-2.1.0/src/htpolynet/resources → htpolynet-2.3.0/src/htpolynet/geometry}/__init__.py +0 -0
  268. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/geometry/bondlist.py +0 -0
  269. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/geometry/lattice.py +0 -0
  270. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/geometry/linkcell.py +0 -0
  271. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/geometry/matrix4.py +0 -0
  272. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/geometry/ring.py +0 -0
  273. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/io/__init__.py +0 -0
  274. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/io/gro.py +0 -0
  275. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/io/mol2.py +0 -0
  276. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/io/pdb.py +0 -0
  277. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/repair/__init__.py +0 -0
  278. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/repair/cyanate_cap.py +0 -0
  279. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/repair/topology_surgery.py +0 -0
  280. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/README.md +0 -0
  281. {htpolynet-2.1.0/src/htpolynet/utils → htpolynet-2.3.0/src/htpolynet/resources}/__init__.py +0 -0
  282. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +0 -0
  283. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +0 -0
  284. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +0 -0
  285. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +0 -0
  286. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +0 -0
  287. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/README.md +0 -0
  288. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
  289. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
  290. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
  291. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/min.mdp +0 -0
  292. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/npt.mdp +0 -0
  293. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
  294. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
  295. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
  296. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
  297. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
  298. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
  299. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
  300. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
  301. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
  302. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
  303. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
  304. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
  305. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/inputs/STY.mol2 +0 -0
  306. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
  307. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
  308. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
  309. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
  310. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
  311. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
  312. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
  313. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
  314. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
  315. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -0
  316. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
  317. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
  318. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
  319. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -0
  320. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -0
  321. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
  322. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
  323. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/resources/tcl/render.tcl +0 -0
  324. {htpolynet-2.1.0/tests → htpolynet-2.3.0/src/htpolynet/utils}/__init__.py +0 -0
  325. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/utils/checkpoint.py +0 -0
  326. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/utils/dataframetools.py +0 -0
  327. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/utils/inputcheck.py +0 -0
  328. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/utils/stringthings.py +0 -0
  329. {htpolynet-2.1.0 → htpolynet-2.3.0}/src/htpolynet/utils/vmd_viz.py +0 -0
  330. {htpolynet-2.1.0/tests/unit → htpolynet-2.3.0/tests}/__init__.py +0 -0
  331. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/conftest.py +0 -0
  332. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/fixtures/config1.gro +0 -0
  333. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/fixtures/config1.top +0 -0
  334. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/fixtures/config2.gro +0 -0
  335. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/fixtures/config2.top +0 -0
  336. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/fixtures/items31.edr +0 -0
  337. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/fixtures/items43.edr +0 -0
  338. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/fixtures/items45.edr +0 -0
  339. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/fixtures/short.mdp +0 -0
  340. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_bondtemplate.py +0 -0
  341. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_configuration.py +0 -0
  342. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_dataframetools.py +0 -0
  343. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_linkcell_pierce.py +0 -0
  344. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_projectfilesystem.py +0 -0
  345. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_ring.py +0 -0
  346. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_ring_pierce_figs.py +0 -0
  347. {htpolynet-2.1.0 → htpolynet-2.3.0}/tests/unit/test_topology/test.top +0 -0
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: htpolynet
3
+ description: Build crosslinked polymer systems with htpolynet — authoring a run configuration, parameterizing monomers, running a cure, and reading the results. Use when the task involves an htpolynet YAML config, the `htpolynet` command (run, input-check, gen-slurm-script, plots, postsim, analyze, make-viz), a monomer's active form or sacrificial hydrogens, a cure that stalls below its target conversion, or sizing an htpolynet build for a cluster.
4
+ ---
5
+
6
+ # Working with htpolynet
7
+
8
+ **Read `docs/source/user-guide/building-a-system.rst` first.** It is the
9
+ procedure, start to finish, and it is maintained alongside the code. This
10
+ file exists to route you there and to carry the few things that are easy to
11
+ get wrong before you get that far. Do not restate the docs here; when they
12
+ and this file disagree, the docs are right.
13
+
14
+ ## Start from an example, never from an empty file
15
+
16
+ `htpolynet fetch-example <n>` unpacks a working configuration. Pick the one
17
+ closest in **reaction topology** — chain growth, A2+B3 step growth,
18
+ cyclotrimerization — not the one closest in chemistry. Adapt it. Writing a
19
+ config from scratch is the slowest route and the one that produces silent
20
+ errors.
21
+
22
+ Run the example unmodified once before editing, to confirm the toolchain and
23
+ to get a known-good log to diff against.
24
+
25
+ ## Monomers are described in their active form
26
+
27
+ The most common conceptual error, and it produces a build that completes and
28
+ is wrong rather than one that fails. htpolynet conserves valence: bonding
29
+ atoms each give up a sacrificial hydrogen, so you describe the monomer with
30
+ its reactive sites already saturated. Styrene is described as ethylbenzene.
31
+ See `docs/source/user-guide/molecular-structure-inputs.rst`.
32
+
33
+ In SMILES bracket atoms the hydrogen count is explicit: `[C:1]` means *zero*
34
+ implicit hydrogens. For an sp³ carbon you almost always want `[CH2:1]` or
35
+ `[CH3:1]`. A wrong count usually surfaces much later as a missing GAFF angle
36
+ parameter in `tleap`.
37
+
38
+ ## Subcommand routing
39
+
40
+ | Intent | Command |
41
+ |---|---|
42
+ | Build a system | `htpolynet run <cfg>` |
43
+ | Size it before queueing | `htpolynet input-check <cfg>` |
44
+ | Stop after parameterization | `htpolynet run --param-only <cfg>` |
45
+ | Submit to a cluster | `htpolynet gen-slurm-script <cfg>` |
46
+ | Plot a finished build | `htpolynet plots build --proj <dir>` |
47
+ | Post-build MD / analysis | `htpolynet postsim`, `htpolynet analyze` |
48
+ | Rebuild VMD viz files | `htpolynet make-viz` |
49
+ | Report the environment | `htpolynet info` |
50
+
51
+ ## Non-obvious facts
52
+
53
+ - **The container image cannot use a GPU.** Its Gromacs is conda-forge,
54
+ built against OpenCL, which Gromacs no longer uses for NVIDIA devices.
55
+ Target CPU partitions; never suggest `--gres=gpu` or `--nv`.
56
+ - **Size core requests from `htpolynet input-check`**, which reports the
57
+ initial atom count.
58
+ - **A cure stalling below its target conversion** is usually a reaction
59
+ template that never matches — suspect `symmetry_equivalent_atoms` and
60
+ reactive-atom names before suspecting the chemistry.
61
+ - **Builds are not reproducible run to run.** There is no seed control, so
62
+ replicas come free but an exact rebuild does not. Record the commit.
63
+
64
+ ## Do not
65
+
66
+ - Do not write workarounds into this file. If the tool surprises a user in a
67
+ way that requires a ritual to avoid, that is a bug: fix it in code, or file
68
+ it in `ROADMAP.md` with enough context to act on later. A skill that
69
+ teaches people to route around a defect keeps the defect.
70
+ - Do not hand-roll a release, a version bump, or a `CHANGELOG` rotation; see
71
+ `CLAUDE.md`.
@@ -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
@@ -32,5 +32,5 @@ jobs:
32
32
  file: docker/Dockerfile
33
33
  push: true
34
34
  tags: |
35
- ghcr.io/abramsgroup/htpolynet:latest
36
- ghcr.io/abramsgroup/htpolynet:${{ github.sha }}
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
 
@@ -7,6 +7,275 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.3.0] - 2026-08-23
11
+
12
+ ### Fixed
13
+
14
+ - **A cached parameterization is no longer reused for a run that asked for
15
+ different AmberTools directives.** `molecules/parameterized` is keyed on
16
+ molecule name alone, and nothing in that key reflected the charge method.
17
+ A configuration specifying `charge_method: bcc` therefore reused, without
18
+ warning, a `gas` parameterization checked into the user library under the
19
+ same residue name, logging only `Using cached parameterization for TAZ`.
20
+ Measured on a cyanate-ester triazine, the cached `gas` entry carries ring
21
+ C +0.1185 / N -0.2249 where a real `bcc` run gives +0.6539 / -0.7160 --
22
+ 5.5x on the charge of the crosslink node -- and the result was a network
23
+ built with `bcc` on one monomer and Gasteiger on another, with nothing in
24
+ the output recording it. The failure was silent and invalidated results
25
+ without failing the build.
26
+
27
+ Each parameterization now writes a `.parm` record beside its
28
+ gro/top/itp/tpx/grx files listing the `charge_method`, `net_charge` and
29
+ `atom_type` that produced it, and that record is checked into the library
30
+ with them. A run whose directives disagree with the record treats the
31
+ cache as a miss and re-parameterizes, saying which directives differed.
32
+
33
+ A library entry written before this release carries no record. Those are
34
+ still used -- an existing library keeps working rather than
35
+ re-parameterizing wholesale -- but each one logs a warning naming the
36
+ charge method that could not be verified, and the parameterization stage
37
+ ends with a block listing every such molecule and the count. Rebuild them
38
+ with `--force-parameterization` if you need certainty about what a build
39
+ used.
40
+
41
+ Re-parameterizing after a mismatch checks its output in only under
42
+ `--force-checkin`, so a library entry is never silently replaced by one
43
+ built with different directives.
44
+
45
+ ### Added
46
+
47
+ - `ambertools.net_charge` and `ambertools.atom_type` configuration
48
+ directives, defaulting to `0` and `gaff`. The net charge was previously
49
+ hardcoded as `-nc 0` in the antechamber invocation, so an ionic or
50
+ zwitterionic monomer was parameterized as though it were neutral with no
51
+ way to say otherwise. The defaults reproduce the previous commands
52
+ exactly.
53
+
54
+ - A procedural page in the user guide, **Building a System, Start to
55
+ Finish**. The guide was strong on reference and had nothing on order of
56
+ operations: start from the nearest bundled example rather than an empty
57
+ file, describe monomers in their active form, check what you can before
58
+ spending compute, and a short list of failures that are known rather than
59
+ mysterious. It states plainly what `input-check` does not yet verify and
60
+ that there is no seed control, so builds are not reproducible run to run.
61
+
62
+ - A Claude skill (`.claude/skills/htpolynet/`) for users working in a clone
63
+ of the repository. It routes to the guide rather than restating it, and
64
+ carries the subcommand table and the handful of facts that are easy to get
65
+ wrong early.
66
+
67
+ - Test coverage for the parameterization record: 34 tests comparing records
68
+ without external tools, and 6 that run antechamber under both charge
69
+ methods to confirm the record describes what actually ran, that the
70
+ directive it guards changes the charges, and that a library holding a
71
+ `gas` entry refuses a `bcc` request while still reusing it for a `gas`
72
+ one. The latter skip when the AmberTools chain is absent.
73
+
74
+ ### Changed
75
+
76
+ - The `-lib` description in the user guide corrected. It said htpolynet
77
+ would "check-in the results of parameterized molecules ... in
78
+ `lib/molecules/parameterized`", which is false: `-lib` governs lookup
79
+ only, and check-in always goes to the per-user cache at `~/.htpolynet`
80
+ (or `$HTPOLYNET_CACHE`). A user who set `-lib` expecting to contain a
81
+ run's output was not contained, and nothing announced the writes.
82
+ `HTPOLYNET_CACHE` is now documented as the variable that actually governs
83
+ where products land.
84
+
85
+ - The user guide's "Parameterization caching" section corrected to match the
86
+ new behavior. It stated that a stale entry is silently reused when you
87
+ change "SMILES, atom-naming, or charge method" and that the cache is
88
+ "keyed by molecule name only"; the charge-method half of the first and all
89
+ of the second are no longer true. The warning now covers exactly what the
90
+ record does not: a constituent's structure, atom-naming or geometry
91
+ changing without a rename.
92
+
93
+ - `--force-checkin`'s help text corrected. It said "force check-in of
94
+ generated parameter files to the system library", which reads as though
95
+ check-in happens only when the flag is given. It does not: a molecule
96
+ whose name the library does not yet hold is checked in either way, and the
97
+ flag governs only whether an entry already there is *overwritten*. It
98
+ also named the wrong library -- check-in goes to the per-user library at
99
+ `~/.htpolynet` (or `$HTPOLYNET_CACHE`), not the system library. Behavior
100
+ is unchanged.
101
+
102
+ ## [2.2.0] - 2026-08-23
103
+
104
+ ### Changed
105
+
106
+ - Container docs' HPC section now leads with `htpolynet gen-slurm-script`
107
+ instead of a hand-written batch script -- the subcommand is already
108
+ Apptainer-aware (`--sif`), but was documented only in `usage.rst`,
109
+ so container users had no reason to find it. The old example
110
+ defaulted to `--gres=gpu:1` and `--nv`, which is actively wrong for
111
+ this image (see the GPU entry under Fixed); replaced with a warning
112
+ explaining why CPU partitions are the right target, plus guidance on
113
+ sizing cores against system size and keeping the submit directory off
114
+ NFS.
115
+ - `rdkit` promoted from the `[smiles]` optional extra to a core
116
+ runtime dependency. Every depot example uses atom-mapped SMILES
117
+ (`[CH:1]`, `[NH2:2]`, etc.), so RDKit is required for any normal
118
+ user workflow; the obabel-only fallback that the extra was
119
+ guarding remains supported but isn't exercised by anything we
120
+ ship. `pip install htpolynet` (or `uv pip install -e .` from the
121
+ repo) now installs RDKit automatically; `'htpolynet[smiles]'` is
122
+ no longer needed (and is gone from `install.rst`).
123
+ - Example 5 (`5-htpb-ipdi.yaml`) retuned for shorter wall-clock.
124
+ The saving comes from a smaller system: the monomer pool drops
125
+ from 125/50/50 to 50/20/20 (IPD/DHT/THT), keeping IPD at
126
+ (2·DHT + 3·THT)/2 so every crosslinker still has both NCO groups
127
+ spoken for at full conversion. Precure anneal segments go 500 →
128
+ 200 ps and postcure postequilibration 1000 → 200 ps.
129
+ Densification was re-balanced for the smaller box in the other
130
+ direction — `initial_density` 50 → 10 kg/m³ to give the long HTPB
131
+ chains room to relax without overlap, and NPT `repeat` 20 → 50 so
132
+ the looser start still reaches target density — so densification
133
+ itself does more work, on a much smaller system. The build still
134
+ converges.
135
+
136
+ ### Added
137
+
138
+ - **CI now runs the unit suite** (`.github/workflows/test.yml`), on pushes
139
+ to `main` and on every pull request, across Python 3.10 and 3.13. Nothing
140
+ ran the tests automatically before, which is how a broken import sat in
141
+ `test_resources.py` aborting collection indefinitely.
142
+ - Tests that shell out to `gmx` / `antechamber` / `tleap` / `parmchk2` now
143
+ skip when those binaries are absent instead of failing, so a runner with
144
+ no MD toolchain still reports the ~250 tests that do not need one (in
145
+ under 4 seconds).
146
+ - Test coverage for `external/slurm.py` (0% -> 98%),
147
+ `external/smiles_input.py` (0% -> 84%), `utils/inputcheck.py`
148
+ (0% -> 70%), and `analysis/plot.py` (6.7% -> 34%), none of which had
149
+ any. Overall coverage 34.4% -> 38.8%. The plot smoke tests were
150
+ checked against the pre-fix module under matplotlib 3.11 and do fail
151
+ there, so they would have caught the `cm.get_cmap` removal.
152
+ - Docker image now carries an `org.opencontainers.image.source` label,
153
+ linking the published GHCR package back to the repository. Without
154
+ it the package is orphaned: it doesn't appear on the repo page and
155
+ doesn't inherit repository-based access permissions.
156
+ - `test` optional-dependency extra (`uv run --extra test pytest tests/unit`),
157
+ with `dev` kept as an alias so both spellings work.
158
+ - `scripts/run_all_examples.sh`: fail-fast preflight that checks
159
+ every required native tool (`htpolynet`, `antechamber`,
160
+ `parmchk2`, `tleap`, `gmx`, `obabel`, `dot`) is on `PATH` before
161
+ starting any build. Better than hitting the first missing
162
+ binary hours into a partial run. Header docstring also gains a
163
+ Prerequisites block pointing at `install.rst` for setup.
164
+ - Docker image now built on `condaforge/miniforge3:latest` (was
165
+ `continuumio/miniconda3:latest`). Miniforge is community-
166
+ maintained, conda-forge only, no Anaconda Inc. terms-of-service
167
+ exposure. Package installs switched from `conda` to `mamba` for
168
+ faster solves. Verified end-to-end: built container's
169
+ `antechamber`, `gmx 2025.4-conda_forge`, `obabel`, `parmed`,
170
+ `rdkit`, and `htpolynet 2.1.0` all callable; `htpolynet
171
+ fetch-example 6 && htpolynet input-check` round-trips.
172
+ - `install.rst` rewritten around the uv + Miniforge workflow: per-
173
+ repo `uv venv` + `uv pip install -e .` for the Python side,
174
+ separate `mamba create -n gromacs` / `mamba create -n ambertools`
175
+ envs for the native MD binaries (both env bins appended to PATH
176
+ in `.bashrc`). Documents `uv tool install --editable .` as the
177
+ way to get a global `htpolynet` command callable from any shell.
178
+ Legacy conda-only one-stop install demoted to a subsection.
179
+ - `htpolynet.utils.profiling` (moved from `htpolynet.profiling`).
180
+ Small utility module — fits utils/ scope; keeps the package root
181
+ focused on actual subpackages. Three internal call sites
182
+ updated.
183
+
184
+ ### Fixed
185
+
186
+ - **API reference documented a module that no longer exists.**
187
+ `docs/source/htpolynetpackage.rst` autodoc'd `htpolynet.driver`,
188
+ removed in the 2.0 refactor, so the package's top-level API section
189
+ rendered empty; it now documents `htpolynet.cli`. The same page was
190
+ missing nine modules that do exist -- most notably the entire
191
+ `repair` subpackage (`repair.cyanate_cap`, `repair.topology_surgery`,
192
+ i.e. the postcure-repair machinery), plus `external.slurm`,
193
+ `external.smiles_input`, `geometry.lattice`, `utils.profiling`, and
194
+ `utils.vmd_viz`. A duplicated `htpolynet.core` heading was merged.
195
+ - `release-history.rst` appeared in no toctree, so the pre-2.0 release
196
+ history (1.0.7.2 back to 0.0.1, which `CHANGELOG.md` does not cover)
197
+ was unreachable from the docs. Linked from `index.rst`; its 2.0.0
198
+ date corrected from 2026-04-15 to 2026-05-07 to match the tag.
199
+ - Two docstrings (`BondTemplate.matches`,
200
+ `utils.profiling.classify_command`) opened bullet lists with no
201
+ preceding blank line, which docutils rejects; both rendered as
202
+ errors. `conf.py` also pointed `html_static_path` at a
203
+ `docs/source/_static` that did not exist. The docs now build with
204
+ zero warnings.
205
+ - **The unit suite could not run at all.** `tests/unit/test_resources.py`
206
+ imported `RuntimeLibrary` from `htpolynet.utils.projectfilesystem` and
207
+ `Software` from `htpolynet.external.software`; neither symbol nor that
208
+ module path survived the 2.0 refactor. Because the imports were at
209
+ module scope, collection aborted for the *entire* `tests/unit` tree, so
210
+ `pytest tests/unit` had been failing outright rather than reporting
211
+ results. Rewritten against the current `SystemLibrary` API (15 tests).
212
+ - Two `test_chain.py` tests asserted exceptions (`'This is a bug - no
213
+ i-chain!'` / `'no j-chain!'`) that no longer exist anywhere in the
214
+ source: `cure/chain.py` deliberately replaced them with graceful chain
215
+ extension, since bonding to a chain-less atom is legitimate for
216
+ non-vinyl chemistry such as HTPB assembly. Rewritten to assert the
217
+ current semantics, plus a new test for the `create_if_missing=False`
218
+ branch. These had been invisible behind the collection failure above.
219
+ - `test_write_top` wrote its scratch file into the repository. The
220
+ autouse `change_test_dir` fixture chdirs each test into a directory
221
+ inside the source tree, and cleanup only ran on the success path, so
222
+ any failure or interrupt left `tests/unit/test_topology/write_test.top`
223
+ behind. Now uses `tempfile.TemporaryDirectory`.
224
+ - **Every plot call crashed on matplotlib 3.11.** `analysis/plot.py`
225
+ called `matplotlib.cm.get_cmap`, deprecated in 3.7 and removed in
226
+ 3.11, at five sites. Since `pyproject.toml` floors matplotlib at
227
+ `>=3.5` with no ceiling, any reasonably fresh install -- including
228
+ the container image, which tracks latest conda-forge -- died with
229
+ `AttributeError: module 'matplotlib.cm' has no attribute
230
+ 'get_cmap'` at the first density trace, i.e. *after* densification
231
+ had already burned its compute. Replaced with a `_get_cmap()`
232
+ helper that prefers the `matplotlib.colormaps` registry and falls
233
+ back to the legacy call only below 3.5. Caught by running example 6
234
+ on Picotte through the container.
235
+ - GPU usability is now judged on whether the gmx build can actually
236
+ drive the detected devices, not merely on whether its GPU support is
237
+ non-`disabled`. conda-forge (and hence our container) ships an
238
+ OpenCL Gromacs build; `gpu_ids` is populated from nvidia-smi and so
239
+ only ever lists NVIDIA devices, which Gromacs no longer drives via
240
+ OpenCL. The previous check passed that combination through, so a
241
+ `gpu_id` from the config reached an `mdrun` that could not honor it.
242
+ New `software.gpu_unusable_reasons()` centralizes the predicate and
243
+ is used by `_mdrun_cmd`, `_enforce_gpu_consistency`, the startup
244
+ banner, and the `grompp_and_mdrun` backstop, which previously
245
+ duplicated a weaker hardware-only version of the test.
246
+ - Container image was missing the `graphviz` system package, so the
247
+ `dot` binary `htpolynet.analysis.plot.draw_reaction_dag` shells out
248
+ to was absent. `pyproject.toml` declares the `graphviz` Python
249
+ binding but the Dockerfile only apt-installed `openbabel` and
250
+ `gosu`. Failure was silent-ish -- `cure/reaction.py` catches the
251
+ exception and logs `reaction_network.png render failed` -- so
252
+ container builds simply came out with no reaction-network figure.
253
+ Found while porting example 6 to Picotte via Apptainer.
254
+ - `htpolynet plots diag` parser templates: the module-path token
255
+ the matcher keyed on was `HTPolyNet.runtime.my_logger` /
256
+ `HTPolyNet.curecontroller.do_iter` from the pre-2.0 namespace.
257
+ After the module reorganization into `htpolynet.core.runtime` /
258
+ `htpolynet.cure.curecontroller`, both lines silently stopped
259
+ matching and the diag parser produced an empty dataframe →
260
+ `IndexError` at first row access. Templates refreshed to the
261
+ current module paths, and the module-name token dropped from
262
+ `pat_idx` so future renames don't break it again.
263
+ - Reaction-network plot (`plots/reaction_network.png`) replaced
264
+ with a bipartite DAG rendered via graphviz `dot` (was a
265
+ spring-layout networkx render that produced tangled, label-
266
+ overlapping diagrams; example 5 was a 30+ node hairball). Each
267
+ molecule is a rounded box; each reaction is a diamond with edges
268
+ from its reactants and an outgoing edge to its product; nodes are
269
+ colored by role (constituent / intermediate / final) and reaction
270
+ stage (param / build / cure / cap / repair). Procession-
271
+ expanded reactions (e.g. example 5's `polymerization` with
272
+ `procession.count: 15`, which `parse_reaction_list` explodes
273
+ into 16 sequential reactions + 15 `A18_I*` intermediates) are
274
+ collapsed back into one node labeled `(×N)` so the diagram
275
+ matches what the user wrote. New runtime dep: `graphviz` (the
276
+ Python wrapper; also needs the system `dot` binary, a separate
277
+ install).
278
+
10
279
  ## [2.1.0] - 2026-06-01
11
280
 
12
281
  ### Added
@@ -0,0 +1,56 @@
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
+ identifiers:
22
+ - type: doi
23
+ value: 10.5281/zenodo.22070252
24
+ description: >-
25
+ Concept DOI for htpolynet; always resolves to the latest
26
+ archived release.
27
+ url: https://htpolynet.readthedocs.io/
28
+ license: MIT
29
+ version: 2.1.0
30
+ date-released: '2026-06-01'
31
+ keywords:
32
+ - molecular dynamics
33
+ - crosslinked polymers
34
+ - thermosets
35
+ - polymer networks
36
+ - Gromacs
37
+ - GAFF
38
+ preferred-citation:
39
+ type: article
40
+ title: >-
41
+ HTPolyNet: A general system generator for all-atom molecular simulations of
42
+ amorphous crosslinked polymers
43
+ authors:
44
+ - family-names: Huang
45
+ given-names: Ming
46
+ - family-names: Abrams
47
+ given-names: Cameron F.
48
+ email: cfa22@drexel.edu
49
+ affiliation: Drexel University
50
+ journal: SoftwareX
51
+ volume: 21
52
+ start: 101303
53
+ year: 2023
54
+ month: 2
55
+ issn: 2352-7110
56
+ 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.