htpolynet 2.10.0__tar.gz → 2.10.2__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 (358) hide show
  1. {htpolynet-2.10.0 → htpolynet-2.10.2}/CHANGELOG.md +52 -0
  2. {htpolynet-2.10.0 → htpolynet-2.10.2}/PKG-INFO +1 -1
  3. {htpolynet-2.10.0 → htpolynet-2.10.2}/ROADMAP.md +35 -0
  4. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/container-usage.rst +30 -0
  5. {htpolynet-2.10.0 → htpolynet-2.10.2}/pyproject.toml +1 -1
  6. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/molecule.py +75 -18
  7. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/runtime.py +23 -12
  8. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/cure/curecontroller.py +7 -1
  9. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/external/gromacs.py +52 -1
  10. htpolynet-2.10.2/tests/unit/test_mdrun_gpu_options.py +49 -0
  11. htpolynet-2.10.2/tests/unit/test_transrot_turn_scan.py +66 -0
  12. {htpolynet-2.10.0 → htpolynet-2.10.2}/.claude/settings.json +0 -0
  13. {htpolynet-2.10.0 → htpolynet-2.10.2}/.claude/skills/htpolynet/SKILL.md +0 -0
  14. {htpolynet-2.10.0 → htpolynet-2.10.2}/.envrc +0 -0
  15. {htpolynet-2.10.0 → htpolynet-2.10.2}/.github/workflows/conda-forge-sync.yml +0 -0
  16. {htpolynet-2.10.0 → htpolynet-2.10.2}/.github/workflows/docker.yml +0 -0
  17. {htpolynet-2.10.0 → htpolynet-2.10.2}/.github/workflows/docs.yml +0 -0
  18. {htpolynet-2.10.0 → htpolynet-2.10.2}/.github/workflows/release.yaml +0 -0
  19. {htpolynet-2.10.0 → htpolynet-2.10.2}/.github/workflows/test.yml +0 -0
  20. {htpolynet-2.10.0 → htpolynet-2.10.2}/.gitignore +0 -0
  21. {htpolynet-2.10.0 → htpolynet-2.10.2}/.readthedocs.yaml +0 -0
  22. {htpolynet-2.10.0 → htpolynet-2.10.2}/CITATION.cff +0 -0
  23. {htpolynet-2.10.0 → htpolynet-2.10.2}/CLAUDE.md +0 -0
  24. {htpolynet-2.10.0 → htpolynet-2.10.2}/LICENSE +0 -0
  25. {htpolynet-2.10.0 → htpolynet-2.10.2}/MANIFEST.in +0 -0
  26. {htpolynet-2.10.0 → htpolynet-2.10.2}/README.md +0 -0
  27. {htpolynet-2.10.0 → htpolynet-2.10.2}/docker/Dockerfile +0 -0
  28. {htpolynet-2.10.0 → htpolynet-2.10.2}/docker/compose.yml +0 -0
  29. {htpolynet-2.10.0 → htpolynet-2.10.2}/docker/docker-entrypoint.sh +0 -0
  30. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/Makefile +0 -0
  31. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/README.rst +0 -0
  32. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/make.bat +0 -0
  33. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/requirements.txt +0 -0
  34. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/_static/.gitkeep +0 -0
  35. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/_static/htpolynet-favicon.ico +0 -0
  36. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/_static/htpolynet-landing.jpg +0 -0
  37. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/_static/htpolynet-logo-dark.png +0 -0
  38. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/_static/htpolynet-logo-light.png +0 -0
  39. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/changelog.rst +0 -0
  40. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/conf.py +0 -0
  41. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +0 -0
  42. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/0-liquid-styrene/index.rst +0 -0
  43. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +0 -0
  44. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +0 -0
  45. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +0 -0
  46. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/0-liquid-styrene/results.rst +0 -0
  47. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/0-liquid-styrene/run.rst +0 -0
  48. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/configuration.rst +0 -0
  49. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/index.rst +0 -0
  50. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/introduction.rst +0 -0
  51. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/monomer.rst +0 -0
  52. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/STY.png +0 -0
  53. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/STYCC.png +0 -0
  54. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
  55. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
  56. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
  57. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
  58. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
  59. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +0 -0
  60. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
  61. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
  62. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
  63. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/pics/styrene-polymerization.png +0 -0
  64. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/postsim.rst +0 -0
  65. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/reactions.rst +0 -0
  66. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/results.rst +0 -0
  67. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/1-polystyrene/run.rst +0 -0
  68. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +0 -0
  69. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +0 -0
  70. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +0 -0
  71. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/BPA.png +0 -0
  72. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/GMA.png +0 -0
  73. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/HIE.png +0 -0
  74. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
  75. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
  76. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
  77. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.eps +0 -0
  78. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.fig +0 -0
  79. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.png +0 -0
  80. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +0 -0
  81. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
  82. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
  83. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
  84. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/p1-traces.png +0 -0
  85. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
  86. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.eps +0 -0
  87. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.fig +0 -0
  88. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.png +0 -0
  89. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +0 -0
  90. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +0 -0
  91. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +0 -0
  92. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +0 -0
  93. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +0 -0
  94. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +0 -0
  95. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +0 -0
  96. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +0 -0
  97. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-epoxy.png +0 -0
  98. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-labelled.png +0 -0
  99. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-2d.png +0 -0
  100. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-labelled.png +0 -0
  101. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
  102. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
  103. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
  104. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +0 -0
  105. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
  106. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
  107. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
  108. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.eps +0 -0
  109. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.fig +0 -0
  110. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.png +0 -0
  111. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/equil-rho_v_ns.png +0 -0
  112. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/postsim-typical.png +0 -0
  113. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-e.png +0 -0
  114. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-equil-rho_v_ns.png +0 -0
  115. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-rho_v_ns.png +0 -0
  116. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-tg.png +0 -0
  117. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r1.png +0 -0
  118. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r2.png +0 -0
  119. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r3.png +0 -0
  120. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
  121. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/rho_v_ns.png +0 -0
  122. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-e.png +0 -0
  123. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-tg.png +0 -0
  124. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +0 -0
  125. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +0 -0
  126. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +0 -0
  127. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +0 -0
  128. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +0 -0
  129. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +0 -0
  130. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +0 -0
  131. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +0 -0
  132. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
  133. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
  134. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
  135. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +0 -0
  136. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
  137. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
  138. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
  139. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
  140. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +0 -0
  141. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +0 -0
  142. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +0 -0
  143. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +0 -0
  144. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +0 -0
  145. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/index.rst +0 -0
  146. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +0 -0
  147. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +0 -0
  148. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
  149. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
  150. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
  151. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +0 -0
  152. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
  153. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
  154. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
  155. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
  156. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +0 -0
  157. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +0 -0
  158. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/results.rst +0 -0
  159. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/5-htpb-ipdi/run.rst +0 -0
  160. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +0 -0
  161. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/index.rst +0 -0
  162. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +0 -0
  163. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +0 -0
  164. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +0 -0
  165. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
  166. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
  167. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
  168. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
  169. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
  170. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
  171. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
  172. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +0 -0
  173. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +0 -0
  174. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/results.rst +0 -0
  175. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/6-cyanate-ester/run.rst +0 -0
  176. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/example-tutorials/index.rst +0 -0
  177. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/htpolynetpackage.rst +0 -0
  178. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/index.rst +0 -0
  179. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/install.rst +0 -0
  180. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/references/index.rst +0 -0
  181. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/references/mol2-reference.pdf +0 -0
  182. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/references.bib +0 -0
  183. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/CURE.odg +0 -0
  184. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/bond_filter.odg +0 -0
  185. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/building-a-system.rst +0 -0
  186. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
  187. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
  188. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/configs/configs-for-run.rst +0 -0
  189. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/configuration-files.rst +0 -0
  190. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/flow1.odg +0 -0
  191. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/flow1yaml.odg +0 -0
  192. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/hydrogenated.eps +0 -0
  193. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/hydrogenated.fig +0 -0
  194. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/index.rst +0 -0
  195. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/molecular-structure-inputs.rst +0 -0
  196. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/periodic-networks.rst +0 -0
  197. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/STY.png +0 -0
  198. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/STYCC.png +0 -0
  199. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
  200. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/bond_filter.png +0 -0
  201. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
  202. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
  203. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/hydrogenated.png +0 -0
  204. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
  205. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
  206. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/postcure-repair.rst +0 -0
  207. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/program-flow.rst +0 -0
  208. {htpolynet-2.10.0 → htpolynet-2.10.2}/docs/source/user-guide/usage.rst +0 -0
  209. {htpolynet-2.10.0 → htpolynet-2.10.2}/scripts/check-conda-sync.py +0 -0
  210. {htpolynet-2.10.0 → htpolynet-2.10.2}/scripts/release.sh +0 -0
  211. {htpolynet-2.10.0 → htpolynet-2.10.2}/scripts/render-detail.sh +0 -0
  212. {htpolynet-2.10.0 → htpolynet-2.10.2}/scripts/render-detail.tcl +0 -0
  213. {htpolynet-2.10.0 → htpolynet-2.10.2}/scripts/render-snapshot.sh +0 -0
  214. {htpolynet-2.10.0 → htpolynet-2.10.2}/scripts/run_all_examples.sh +0 -0
  215. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/__init__.py +0 -0
  216. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/analysis/__init__.py +0 -0
  217. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/analysis/analyze.py +0 -0
  218. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/analysis/plot.py +0 -0
  219. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/analysis/postsim.py +0 -0
  220. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/analysis/utils.py +0 -0
  221. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/cli.py +0 -0
  222. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/__init__.py +0 -0
  223. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/bondtemplate.py +0 -0
  224. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/configuration.py +0 -0
  225. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/coordinates.py +0 -0
  226. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/paramcache.py +0 -0
  227. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/projectfilesystem.py +0 -0
  228. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/topocoord.py +0 -0
  229. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/core/topology.py +0 -0
  230. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/cure/__init__.py +0 -0
  231. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/cure/chain.py +0 -0
  232. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/cure/expandreactions.py +0 -0
  233. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/cure/reaction.py +0 -0
  234. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/external/__init__.py +0 -0
  235. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/external/ambertools.py +0 -0
  236. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/external/command.py +0 -0
  237. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/external/slurm.py +0 -0
  238. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/external/smiles_input.py +0 -0
  239. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/external/software.py +0 -0
  240. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/geometry/__init__.py +0 -0
  241. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/geometry/bondlist.py +0 -0
  242. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/geometry/lattice.py +0 -0
  243. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/geometry/linkcell.py +0 -0
  244. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/geometry/matrix4.py +0 -0
  245. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/geometry/ring.py +0 -0
  246. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/io/__init__.py +0 -0
  247. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/io/gro.py +0 -0
  248. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/io/mol2.py +0 -0
  249. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/io/pdb.py +0 -0
  250. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/repair/__init__.py +0 -0
  251. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/repair/cyanate_cap.py +0 -0
  252. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/repair/topology_surgery.py +0 -0
  253. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/README.md +0 -0
  254. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/__init__.py +0 -0
  255. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/claude/SKILL.md +0 -0
  256. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +0 -0
  257. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/example_depot/1-polystyrene.yaml +0 -0
  258. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +0 -0
  259. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +0 -0
  260. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +0 -0
  261. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +0 -0
  262. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +0 -0
  263. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/README.md +0 -0
  264. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
  265. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
  266. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
  267. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/min.mdp +0 -0
  268. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/npt.mdp +0 -0
  269. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
  270. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
  271. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
  272. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
  273. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
  274. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
  275. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
  276. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
  277. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
  278. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
  279. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
  280. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
  281. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/inputs/STY.mol2 +0 -0
  282. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
  283. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
  284. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
  285. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
  286. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
  287. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
  288. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
  289. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
  290. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
  291. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -0
  292. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
  293. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
  294. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
  295. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -0
  296. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -0
  297. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
  298. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
  299. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/resources/tcl/render.tcl +0 -0
  300. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/schema/base.yaml +0 -0
  301. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/__init__.py +0 -0
  302. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/banner.py +0 -0
  303. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/checkpoint.py +0 -0
  304. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/convergence.py +0 -0
  305. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/dataframetools.py +0 -0
  306. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/inputcheck.py +0 -0
  307. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/logsetup.py +0 -0
  308. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/profiling.py +0 -0
  309. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/stringthings.py +0 -0
  310. {htpolynet-2.10.0 → htpolynet-2.10.2}/src/htpolynet/utils/vmd_viz.py +0 -0
  311. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/__init__.py +0 -0
  312. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/conftest.py +0 -0
  313. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/__init__.py +0 -0
  314. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/fixtures/config1.gro +0 -0
  315. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/fixtures/config1.top +0 -0
  316. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/fixtures/config2.gro +0 -0
  317. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/fixtures/config2.top +0 -0
  318. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/fixtures/items31.edr +0 -0
  319. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/fixtures/items43.edr +0 -0
  320. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/fixtures/items45.edr +0 -0
  321. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/fixtures/short.mdp +0 -0
  322. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_bondtemplate.py +0 -0
  323. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_cap_placement.py +0 -0
  324. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_chain.py +0 -0
  325. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_completion_bias.py +0 -0
  326. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_conda_sync.py +0 -0
  327. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_configuration.py +0 -0
  328. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_convergence.py +0 -0
  329. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_cure_site_functionality.py +0 -0
  330. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_dataframetools.py +0 -0
  331. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_density_gate.py +0 -0
  332. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_gpu_usability.py +0 -0
  333. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_gromacs_get_energy_menu.py +0 -0
  334. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_gromacs_gmx_energy_trace.py +0 -0
  335. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_inputcheck.py +0 -0
  336. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_linkcell_pierce.py +0 -0
  337. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_mol2_bond_fallback.py +0 -0
  338. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_molecule_charge_report.py +0 -0
  339. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_moleculetype_name.py +0 -0
  340. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_paramcache.py +0 -0
  341. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_paramcache_ambertools.py +0 -0
  342. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_parameterize_react.py +0 -0
  343. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_plot_smoke.py +0 -0
  344. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_projectfilesystem.py +0 -0
  345. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_relax_instrumentation.py +0 -0
  346. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_repair_charge_neutrality.py +0 -0
  347. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_repair_conversion.py +0 -0
  348. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_resources.py +0 -0
  349. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_ring.py +0 -0
  350. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_ring_pierce_figs.py +0 -0
  351. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_setup_claude.py +0 -0
  352. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_sibling_templates.py +0 -0
  353. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_slurm_script.py +0 -0
  354. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_smiles_input.py +0 -0
  355. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_software_provenance.py +0 -0
  356. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_topology/test.top +0 -0
  357. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_topology.py +0 -0
  358. {htpolynet-2.10.0 → htpolynet-2.10.2}/tests/unit/test_user_frcmod.py +0 -0
@@ -7,6 +7,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.10.2] - 2026-09-17
11
+
12
+ ### Fixed
13
+
14
+ - **Templates for crowded monomers could start with atoms on top of each
15
+ other, and AM1-BCC/ABCG2 charges then failed.** When htpolynet built a
16
+ linked-product template, it attached the incoming molecule along the new
17
+ bond but never turned it about that bond. Its clash check also compared the
18
+ moved piece with its own pre-move position. With tetramethylbisphenol F
19
+ (TMB), whose methyls flank each reacting oxygen, every triazine template
20
+ started with a methyl hydrogen 0.65-1.26 A from a ring atom. On one triply
21
+ substituted template, AmberTools 26's sqm then failed to converge ("Cannot
22
+ properly run sqm"), which stopped parameterization.
23
+
24
+ The placement now scans turns about the new bond, in 10 degree steps, and
25
+ keeps the one farthest from the residues that stay put. Every TMB template
26
+ now starts at 1.50 A or more. The six triply substituted TMB templates
27
+ were run with ABCG2 on AmberTools 26: five, including the geometry that
28
+ failed before, completed, and the sixth converged its SCF and was still
29
+ optimizing when this was written. On these crowded molecules the
30
+ optimization is slow, 40 minutes to 2.6 hours each, run three at a time. Charges and atom types of all 123
31
+ templates in the shipped examples, which use gas charges, are unchanged. A
32
+ template that still starts with a contact under 1 A is now logged as a
33
+ warning.
34
+
35
+ ## [2.10.1] - 2026-09-16
36
+
37
+ ### Fixed
38
+
39
+ - **Asking for `pme: gpu` or `update: gpu` in `mdrun_options` stopped the
40
+ build at its first minimization.** The same options go to every `mdrun`,
41
+ and GROMACS refuses both tasks on a GPU without a dynamical integrator.
42
+ For minimization stages they now become `auto`, and so does `bonded`, which
43
+ hasn't been checked with a minimizer. Dynamics gets the options unchanged.
44
+
45
+ - **The parameterization summary undercounted and named the wrong place.**
46
+ It was printed before the symmetry-, chain- and second-shell-derived
47
+ templates were built, so a run that reused 29 templates reported 11. It
48
+ also always named `~/.htpolynet`, even when `HTPOLYNET_CACHE` pointed
49
+ elsewhere. It now comes after every template exists, reports "N of M
50
+ reused", and names the library and cache actually searched.
51
+
52
+ ### Changed
53
+
54
+ - **The "percolation not assessed" message says when it means "cannot
55
+ assess".** It read as though the outcome were always the correct answer
56
+ for a linear polymer, with the multi-residue crosslinker case as an aside.
57
+ For example 2 that aside is the actual situation: bis-GMA crosslinks
58
+ through junctions a residue-level count cannot see. Noticed by a sweep of
59
+ the shipped examples.
60
+
61
+
10
62
  ## [2.10.0] - 2026-09-15
11
63
 
12
64
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: htpolynet
3
- Version: 2.10.0
3
+ Version: 2.10.2
4
4
  Summary: Automated MD System Builder for Amorphous Network Polymers
5
5
  Project-URL: Source, https://github.com/cameronabrams/htpolynet
6
6
  Project-URL: Documentation, https://htpolynet.readthedocs.io/
@@ -199,6 +199,20 @@ Coverage as of the last measurement: **38.8%** overall.
199
199
 
200
200
  ## Cure and repair
201
201
 
202
+ - **Chain-growth cure leaves whole chains charged.** The v2.10.0 sweep's new
203
+ molecule-charge check found example 1's polystyrene warning: 7 of 49 chains
204
+ over 0.01 e, the largest -0.040 e on the longest (1410-atom) chain, with the
205
+ system total exactly 0. htpolynet-sweep measured the same scale in the two
206
+ preceding sweeps (9 of 49, largest -0.022 and -0.025 e), so it predates the
207
+ check, which merely exposed it. It is about 2-3e-5 e per atom, i.e. a little
208
+ charge per chain-growth bond, which points at the same system-wide
209
+ `adjust_charges` as the item below. Small enough not to matter much per
210
+ atom, but it scales with chain length, so the longest chain is the worst
211
+ off. The fix is the per-molecule settle below; what is not yet known is
212
+ whether the residual comes from the templates disagreeing with their
213
+ instances (a `STY~C1-C2~STY` bond in a long chain is not quite the trimer
214
+ template) or only from the system-wide spread. Measure before fixing.
215
+
202
216
  - **Cure still settles template overcharge system-wide.**
203
217
  `map_from_templates` ends each batch of bonds with one `adjust_charges`
204
218
  over every mapped atom in the system. When the templates are consistent
@@ -936,6 +950,16 @@ Coverage as of the last measurement: **38.8%** overall.
936
950
  for any operand that lacks the table, rather than concatenating a partial
937
951
  table. Bond orders would then need the same single-bond assumption.
938
952
 
953
+ **It has appeared (2026-09-17).** Example 2's stereoisomer copies `GMAS-*`
954
+ have 78 bonds in their topology but only 24 in their `.mol2`, in the
955
+ 2026-09-14 sweep's files too. It shows up only when a cache is *reused*:
956
+ `bond_source_check` then logs "Gromacs/Mol2 bond inconsistency detected"
957
+ once per copy. Sweeps always start from an empty cache, so they never see
958
+ it. `generate_stereoisomers` deep-copies the parent's TopoCoord and writes
959
+ only a `.gro`; where the 24-bond `.mol2` comes from is not yet traced. What
960
+ a reused cache does with the wrong table (ring detection, system `.mol2`
961
+ output) is also unknown. No cyanate-ester molecule has stereoisomer copies.
962
+
939
963
  - **Two gaps left after the percolation check moved to cure sites
940
964
  (2026-09-15).** First, a system that crosslinks through a *multi-residue*
941
965
  molecule -- example 2's GMA (two methacrylate HIE units), example 5's
@@ -951,6 +975,17 @@ Coverage as of the last measurement: **38.8%** overall.
951
975
 
952
976
  ## Simulation defaults
953
977
 
978
+ - **The density-convergence tolerance may be tight for example 6.** In the
979
+ v2.10.0 sweep, example 6 failed the gate for the first time in four sweeps:
980
+ "sem 1.070 exceeds tolerance 1.000" after 6 extensions, with the last window
981
+ at 1112.0 kg/m^3 against 1110.5 and 1111.6 in the two sweeps that converged
982
+ with no extension at all. Monomer charges were byte-identical to the
983
+ previous sweep, so this is run-to-run noise rather than a change -- but the
984
+ build went on into the cure from a box the gate had just called unsettled,
985
+ and said so only in a warning. Worth deciding whether the tolerance should
986
+ scale with system size or window length, and whether failing it should be
987
+ more than a warning.
988
+
954
989
  - **The halogen constraint failure is fixed but not explained.** v2.7.0
955
990
  switched the per-iteration equilibration to `constraints = h-bonds` with
956
991
  `lincs_order = 8`, which took a fluorinated bisphenol from 0 of 7 builds to
@@ -234,6 +234,36 @@ them. Confirm from its GPU banner rather than assuming: if the banner still
234
234
  says ``unusable``, you are running the default image under a ``:cuda`` name,
235
235
  or the container was not given a device.
236
236
 
237
+ Choosing mdrun GPU tasks
238
+ """"""""""""""""""""""""
239
+
240
+ ``gromacs.mdrun_options`` in the configuration is passed to every ``mdrun``
241
+ htpolynet runs for the system: densification, precure, every cure stage,
242
+ repair, and postcure. ``htpolynet postsim`` and ``htpolynet analyze`` use it
243
+ too, but only when given the build's configuration with ``-ocfg``. Each key
244
+ becomes a flag, so this
245
+
246
+ .. code-block:: yaml
247
+
248
+ gromacs:
249
+ mdrun_options:
250
+ nb: gpu
251
+ ntomp: 8
252
+
253
+ runs ``mdrun -nb gpu -ntomp 8``. With the short-range work on the GPU,
254
+ Gromacs 2026's ``auto`` choices also put PME and the coordinate update on the
255
+ GPU wherever they can. Bonded interactions are the exception: ``auto`` keeps
256
+ them on the CPU when PME is on the GPU, so add ``bonded: gpu`` to move them.
257
+ The task-assignment lines near the top of each run's ``.log`` say where each
258
+ task ran.
259
+
260
+ Many of those runs are energy minimizations, and Gromacs refuses
261
+ ``-pme gpu`` and ``-update gpu`` for a minimizer. htpolynet therefore passes
262
+ ``auto`` for ``pme``, ``update`` and ``bonded`` whenever the stage's
263
+ integrator is not a dynamical one, so asking for them explicitly is safe. Everything the cure uses
264
+ otherwise (Berendsen coupling, h-bond constraints with LINCS, simulated
265
+ annealing) is supported with the update on the GPU.
266
+
237
267
  .. note::
238
268
 
239
269
  The ``:cuda`` image is substantially larger, because the CUDA build of
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "htpolynet"
7
- version = "2.10.0"
7
+ version = "2.10.2"
8
8
  authors = [
9
9
  { name="Cameron F Abrams", email="cfa22@drexel.edu" },
10
10
  ]
@@ -51,6 +51,46 @@ def _yield_bonds_as_df(R: Reaction, TC: TopoCoord, resid_mapper) -> pd.DataFrame
51
51
  'order': bondrec['order'], 'reactantName': R.product})
52
52
  return pd.DataFrame(rows)
53
53
 
54
+ _TRANSROT_STEP_DEG_ = 10.0
55
+ """Angular step of the turn scan in Molecule.transrot."""
56
+
57
+ _TRANSROT_WARN_NM_ = 0.10
58
+ """Closest approach, in nm, below which a template's starting geometry is reported as crowded.
59
+
60
+ Contacts of 1.2-1.5 A between the new piece and the rest are routine before
61
+ minimization; below 1 A they have been seen to stop sqm converging (a TMB ring
62
+ methyl H 0.82 A from a triazine N).
63
+ """
64
+
65
+
66
+ def _rotate_about_axis(xyz, point, axis, theta):
67
+ """Rotates points by theta about the line through point along unit vector axis (Rodrigues).
68
+
69
+ Args:
70
+ xyz (numpy.ndarray): (n, 3) positions
71
+ point (numpy.ndarray): a point on the axis
72
+ axis (numpy.ndarray): unit vector along the axis
73
+ theta (float): angle in radians
74
+
75
+ Returns:
76
+ numpy.ndarray: rotated (n, 3) positions
77
+ """
78
+ if theta == 0.0:
79
+ return xyz.copy()
80
+ k = axis / np.linalg.norm(axis)
81
+ K = np.array([[0, -k[2], k[1]], [k[2], 0, -k[0]], [-k[1], k[0], 0]])
82
+ R = np.eye(3) + np.sin(theta) * K + (1.0 - np.cos(theta)) * (K @ K)
83
+ return (xyz - point) @ R.T + point
84
+
85
+
86
+ def _min_distance(a, b):
87
+ """Smallest distance between any point of a and any point of b; inf if either is empty."""
88
+ if len(a) == 0 or len(b) == 0:
89
+ return np.inf
90
+ diff = a[:, np.newaxis, :] - b[np.newaxis, :, :]
91
+ return float(np.sqrt((diff * diff).sum(axis=2)).min())
92
+
93
+
54
94
  class Molecule:
55
95
  def __init__(self, name='', generator:Reaction=None, origin:str=None):
56
96
  self.name = name
@@ -830,7 +870,16 @@ class Molecule:
830
870
  Rj = TC.get_R(from_idx)
831
871
  logger.debug(f'Ri {at_idx} {Ri} {type(Ri)} {Ri.dtype}')
832
872
  logger.debug(f'Rj {from_idx} {Rj} {type(Rj)} {Rj.dtype}')
833
- overall_maximum = (-1.e9, -1, -1)
873
+ # The two sacrificial H's are made to coincide, which puts at_idx, the H's
874
+ # and from_idx on one line. The moving piece can still turn freely about
875
+ # that line, and that freedom is what clears a crowded site: a third
876
+ # tetramethyl bisphenol on a triazine lands its ortho methyl inside the
877
+ # ring at the unrotated placement. So each H pairing is tried at a
878
+ # range of turns, and the one farthest from the residues that stay put
879
+ # wins. (Measuring against all of TC would include the moving piece's
880
+ # own pre-move positions.)
881
+ fixed = C[~C['resNum'].isin(bresids)]
882
+ overall_maximum = (-1.e9, -1, -1, 0.0)
834
883
  coord_trials = {}
835
884
  for myH, myHnm in myHpartners.items(): # keys are globalIdx's, values are names
836
885
  coord_trials[myH] = {}
@@ -838,17 +887,13 @@ class Molecule:
838
887
  logger.debug(f' Rh {myH} {Rh} {Rh.dtype}')
839
888
  Rih = Ri - Rh
840
889
  Rih *= 1.0 / np.linalg.norm(Rih)
890
+ fixed_xyz = fixed.loc[fixed['globalIdx'] != myH, ['posX', 'posY', 'posZ']].to_numpy(dtype=float)
841
891
  for otH, otHnm in otHpartners.items():
842
892
  logger.debug(f'{self.name}: Considering {myH} {otH}')
843
- coord_trials[myH][otH] = deepcopy(BTC)
844
- # logger.debug(f'\n{coord_trials[myH][otH].Coordinates.A.to_string()}')
845
- Rk = coord_trials[myH][otH].get_R(otH)
846
- logger.debug(f'{self.name}: otH {otH} Rk {Rk} {Rk.dtype}')
893
+ aligned = deepcopy(BTC)
894
+ Rk = aligned.get_R(otH)
847
895
  Rkj = Rk - Rj
848
896
  Rkj *= 1.0 / np.linalg.norm(Rkj)
849
- logger.debug(f'Rkj {Rkj} {Rkj.dtype} Rih {Rih} {Rih.dtype}')
850
- #Rhk=Rh-Rk
851
- #rhk=np.linalg.norm(Rhk)
852
897
  cp = np.cross(Rkj,Rih)
853
898
  c = np.dot(Rkj,Rih)
854
899
  v = np.array([[0,-cp[2],cp[1]],[cp[2],0,-cp[0]],[-cp[1],cp[0],0]])
@@ -856,19 +901,31 @@ class Molecule:
856
901
  I = np.array([[1.,0.,0.],[0.,1.,0.],[0.,0.,1.]])
857
902
  # R is the rotation matrix that will rotate donb to align with accb
858
903
  R = I + v + v2 / (1. + c)
859
- # logger.debug(f'{self.name}: R:\n{R}')
860
- # rotate translate all donor atoms!
861
- coord_trials[myH][otH].rotate(R)
862
- Rk = coord_trials[myH][otH].get_R(otH)
904
+ aligned.rotate(R)
905
+ Rk = aligned.get_R(otH)
863
906
  # overlap the two H atoms by translation
864
- Rik = Rh - Rk
865
- coord_trials[myH][otH].translate(Rik)
866
- minD = TC.minimum_distance(coord_trials[myH][otH], self_excludes=[myH], other_excludes=[otH])
867
- logger.debug(f'{self.name}: minD {minD}')
907
+ aligned.translate(Rh - Rk)
908
+ A = aligned.Coordinates.A
909
+ moving_mask = (A['globalIdx'] != otH).to_numpy()
910
+ xyz = A[['posX', 'posY', 'posZ']].to_numpy(dtype=float)
911
+ best = None
912
+ for theta in np.deg2rad(np.arange(0.0, 360.0, _TRANSROT_STEP_DEG_)):
913
+ trial = _rotate_about_axis(xyz, Rh, Rih, theta)
914
+ minD = _min_distance(trial[moving_mask], fixed_xyz)
915
+ if best is None or minD > best[0]:
916
+ best = (minD, theta, trial)
917
+ minD, theta, trial = best
918
+ A[['posX', 'posY', 'posZ']] = trial
919
+ coord_trials[myH][otH] = aligned
920
+ logger.debug(f'{self.name}: {myH}/{otH} best turn {np.rad2deg(theta):.0f} deg, minD {minD}')
868
921
  if minD > overall_maximum[0]:
869
- overall_maximum = (minD, myH, otH)
922
+ overall_maximum = (minD, myH, otH, theta)
870
923
  logger.debug(f'{self.name}: overall_maximum {overall_maximum}')
871
- minD, myH, otH = overall_maximum
924
+ minD, myH, otH, _ = overall_maximum
925
+ if minD < _TRANSROT_WARN_NM_:
926
+ logger.warning(f'{self.name}: the best placement found for the new bond still leaves two atoms '
927
+ f'{minD*10:.2f} A apart; a semi-empirical charge method (bcc, abcg2) may fail to converge '
928
+ f'on this starting geometry')
872
929
  BTC = coord_trials[myH][otH]
873
930
  TC.overwrite_coords(BTC)
874
931
  TC.swap_atom_names(myH, list(myHighestH.keys())[0])
@@ -195,6 +195,28 @@ class Runtime:
195
195
  if k not in current:
196
196
  current[k]=v
197
197
 
198
+ def _report_parameterization_summary(self):
199
+ """Logs how many molecule templates were reused and how many were parameterized.
200
+
201
+ Counted after every derived template (symmetry, C=C chain, and
202
+ second-shell) exists, so the numbers cover everything this run needs;
203
+ a job that must not parameterize anything, e.g. one reading a
204
+ pre-filled read-only cache, can check for "0 freshly parameterized".
205
+ """
206
+ n_cached=sum(1 for M in self.molecules.values() if M.origin=='previously parameterized')
207
+ n_new=sum(1 for M in self.molecules.values() if (M.origin or '').startswith('newly parameterized'))
208
+ if not (n_cached or n_new): return
209
+ where=[]
210
+ if pfs._PFS_ and pfs._PFS_.userlibrary:
211
+ where.append(f'{pfs._PFS_.userlibrary.root}')
212
+ if pfs._USER_CACHE_ is not None:
213
+ where.append(f'{pfs._USER_CACHE_.root}')
214
+ logger.info(f'Parameterization summary: {n_cached} of {n_cached+n_new} molecule templates reused from the library '
215
+ f'({" or ".join(where) or "unknown location"}), {n_new} freshly parameterized.')
216
+ if n_cached:
217
+ logger.info(' to force re-parameterization on the next run, use '
218
+ '`htpolynet run --force-parameterization --force-checkin ...`')
219
+
198
220
  def _read_frcmods(self):
199
221
  """Reads the user frcmod file each constituent names, if any.
200
222
 
@@ -357,18 +379,6 @@ class Runtime:
357
379
  logger.debug(f'Generating: {list(self.molecules.keys())}')
358
380
  for mname,M in self.molecules.items():
359
381
  self._generate_molecule(M,force_parameterization=force_parameterization,force_checkin=force_checkin)
360
- n_cached=sum(1 for M in self.molecules.values() if M.origin=='previously parameterized')
361
- n_new=sum(1 for M in self.molecules.values() if M.origin=='newly parameterized')
362
- if n_cached or n_new:
363
- logger.info(
364
- f'Parameterization summary: {n_cached} reused from cache '
365
- f'(~/.htpolynet/molecules/parameterized/), {n_new} freshly parameterized.'
366
- )
367
- if n_cached:
368
- logger.info(
369
- ' to force re-parameterization on the next run, use '
370
- '`htpolynet run --force-parameterization --force-checkin ...`'
371
- )
372
382
  new_reactions,new_molecules=bondchain_expand_reactions(self.molecules)
373
383
  if len(new_molecules)>0:
374
384
  ess='' if len(new_molecules)==1 else 's'
@@ -392,6 +402,7 @@ class Runtime:
392
402
  self.molecules[mname]=M
393
403
  logger.debug(f'Generated {mname}')
394
404
 
405
+ self._report_parameterization_summary()
395
406
  self._check_frcmod_type_conflicts()
396
407
 
397
408
  for M in self.molecules:
@@ -890,7 +890,13 @@ class CureController:
890
890
  # monomer was mid-chain.
891
891
  if fmax<3:
892
892
  if mask is not None:
893
- logger.info('No residue carries three or more cure-reactive sites, so crosslink percolation is not assessed. That is correct for a linear polymer; a system that crosslinks through a multi-residue molecule -- a dimethacrylate, a multi-arm prepolymer -- is outside what this residue-level check can see.')
893
+ logger.info('Crosslink percolation was not assessed: no residue carries three or more '
894
+ 'cure-reactive sites. For a chain polymer that is the answer -- a fully reacted '
895
+ 'difunctional unit is a chain interior, not a junction. But a system that '
896
+ 'crosslinks through a multi-residue molecule, such as a dimethacrylate built from '
897
+ 'a bisphenol and two methacrylates, does percolate through junctions this '
898
+ 'residue-level count cannot see, and there this line means "cannot assess", not '
899
+ '"does not percolate".')
894
900
  return
895
901
  names=adf.loc[adf['resNum']==func.idxmax(),'resName']
896
902
  resname=names.iloc[0] if len(names) else f'residue {func.idxmax()}'
@@ -60,6 +60,56 @@ def insert_molecules(composition,boxSize,outName,inputs_dir='.',**kwargs):
60
60
  logger.debug(l)
61
61
  raise Exception('need bigger box')
62
62
 
63
+ _DYNAMICAL_INTEGRATORS_ = ('md', 'md-vv', 'md-vv-avek', 'sd', 'bd')
64
+ """GROMACS integrators that do dynamics; the rest (steep, cg, l-bfgs, nm, tpi, ...) do not."""
65
+
66
+ _DYNAMICS_ONLY_GPU_TASKS_ = ('pme', 'update', 'bonded')
67
+ """mdrun tasks not forced onto a GPU without a dynamical integrator.
68
+
69
+ GROMACS refuses ``-pme gpu`` and ``-update gpu`` with a minimizer. Whether it
70
+ accepts ``-bonded gpu`` there has not been checked, and a minimization is
71
+ cheap enough that running its bonded work on the CPU costs nothing that matters.
72
+ """
73
+
74
+
75
+ def mdp_integrator(mdp_filename):
76
+ """Returns the integrator an mdp file selects, lower-cased; 'md' if it does not say.
77
+
78
+ Args:
79
+ mdp_filename (str): mdp file name
80
+
81
+ Returns:
82
+ str: integrator name
83
+ """
84
+ value = mdp_to_dict(mdp_filename).get('integrator', 'md')
85
+ return value.split(';')[0].strip().lower() or 'md'
86
+
87
+
88
+ def mdrun_options_for(mdrun_options, integrator):
89
+ """Returns the mdrun options to use with a given integrator.
90
+
91
+ One ``gromacs.mdrun_options`` serves every stage of a build, minimizations
92
+ included. GROMACS stops with a fatal error when ``-pme gpu`` or
93
+ ``-update gpu`` is given with a minimizer, so for a minimizer these, and
94
+ ``-bonded gpu``, become ``auto``. Dynamics gets the options unchanged.
95
+
96
+ Args:
97
+ mdrun_options (dict): options from the configuration
98
+ integrator (str): the mdp's integrator
99
+
100
+ Returns:
101
+ dict: options to pass to mdrun
102
+ """
103
+ if integrator in _DYNAMICAL_INTEGRATORS_:
104
+ return mdrun_options
105
+ adjusted = dict(mdrun_options)
106
+ for task in _DYNAMICS_ONLY_GPU_TASKS_:
107
+ if str(adjusted.get(task, '')).lower() == 'gpu':
108
+ adjusted[task] = 'auto'
109
+ logger.debug(f'integrator {integrator} cannot run {task} on the GPU; passing -{task} auto for this run')
110
+ return adjusted
111
+
112
+
63
113
  def grompp_and_mdrun(gro='',top='',out='',mdp='',boxSize=[],single_molecule=False,**kwargs):
64
114
  """Launcher for grompp and mdrun.
65
115
 
@@ -75,7 +125,7 @@ def grompp_and_mdrun(gro='',top='',out='',mdp='',boxSize=[],single_molecule=Fals
75
125
  quiet=kwargs.get('quiet',True)
76
126
  ignore_codes=kwargs.get('ignore_codes',[-11])
77
127
  maxwarn=kwargs.get('maxwarn',4)
78
- mdrun_options=kwargs.get('mdrun_options',{})
128
+ mdrun_options=dict(kwargs.get('mdrun_options',{}))
79
129
  for option in ['rdd','dds','dlb','npme','nt','ntpmi','ntomp','ntomp_pme','nb','tunepme','pme','pmefft','bonded','update']:
80
130
  if option in kwargs and not option in mdrun_options:
81
131
  mdrun_options[option]=kwargs[option]
@@ -91,6 +141,7 @@ def grompp_and_mdrun(gro='',top='',out='',mdp='',boxSize=[],single_molecule=Fals
91
141
  run(f'{sw.gmx} {sw.gmx_options} editconf -f {gro}.gro -o {gro} -box {box_str}', quiet=quiet)
92
142
  # nsteps=kwargs.get('nsteps',-2)
93
143
  run(f'{sw.gmx} {sw.gmx_options} grompp -f {mdp}.mdp -c {gro}.gro -p {top}.top -o {out}.tpr -maxwarn {maxwarn}', quiet=quiet)
144
+ mdrun_options = mdrun_options_for(mdrun_options, mdp_integrator(f'{mdp}.mdp'))
94
145
  if 'gpu_id' in mdrun_options:
95
146
  unusable = sw.gpu_unusable_reasons()
96
147
  if unusable:
@@ -0,0 +1,49 @@
1
+ """
2
+
3
+ .. module:: test_mdrun_gpu_options
4
+ :synopsis: one set of mdrun GPU options must work for minimizations as well as dynamics
5
+
6
+ .. moduleauthor: Cameron F. Abrams, <cfa22@drexel.edu>
7
+
8
+ """
9
+ from importlib.resources import files
10
+
11
+ import pytest
12
+
13
+ from htpolynet.external.gromacs import mdp_integrator, mdrun_options_for
14
+
15
+ GPU = {'nb': 'gpu', 'pme': 'gpu', 'bonded': 'gpu', 'update': 'gpu', 'ntomp': 8}
16
+
17
+
18
+ class TestMdrunOptionsFor:
19
+ def test_dynamics_keeps_everything(self):
20
+ assert mdrun_options_for(GPU, 'md') == GPU
21
+
22
+ @pytest.mark.parametrize('integrator', ['steep', 'cg', 'l-bfgs'])
23
+ def test_minimizer_downgrades_only_what_gromacs_rejects(self, integrator):
24
+ got = mdrun_options_for(GPU, integrator)
25
+ assert got['pme'] == 'auto' and got['update'] == 'auto' and got['bonded'] == 'auto'
26
+ assert got['nb'] == 'gpu' and got['ntomp'] == 8
27
+
28
+ def test_explicit_cpu_is_left_alone(self):
29
+ assert mdrun_options_for({'pme': 'cpu', 'update': 'cpu'}, 'steep') == {'pme': 'cpu', 'update': 'cpu'}
30
+
31
+ def test_the_configuration_is_not_mutated(self):
32
+ opts = dict(GPU)
33
+ mdrun_options_for(opts, 'steep')
34
+ assert opts == GPU
35
+
36
+
37
+ class TestMdpIntegrator:
38
+ mdp = files('htpolynet.resources') / 'mdp'
39
+
40
+ @pytest.mark.parametrize('name,expected', [('min', 'steep'), ('drag-min', 'steep'), ('relax-min', 'steep'),
41
+ ('npt', 'md'), ('relax-nvt', 'md')])
42
+ def test_shipped_mdps(self, name, expected):
43
+ # min.mdp writes "integrator = steep;" with the semicolon attached
44
+ assert mdp_integrator(str(self.mdp / f'{name}.mdp')) == expected
45
+
46
+ def test_absent_means_md(self, tmp_path):
47
+ f = tmp_path / 'x.mdp'
48
+ f.write_text('nsteps = 10\n')
49
+ assert mdp_integrator(str(f)) == 'md'
@@ -0,0 +1,66 @@
1
+ """
2
+
3
+ .. module:: test_transrot_turn_scan
4
+ :synopsis: template placement turns the incoming piece to clear crowded sites
5
+
6
+ .. moduleauthor: Cameron F. Abrams, <cfa22@drexel.edu>
7
+
8
+ """
9
+ import numpy as np
10
+ import pytest
11
+
12
+ from htpolynet.core.molecule import _min_distance, _rotate_about_axis
13
+
14
+
15
+ class TestRotateAboutAxis:
16
+ def test_quarter_turn_about_z(self):
17
+ got = _rotate_about_axis(np.array([[1.0, 0.0, 0.0]]), np.zeros(3), np.array([0.0, 0.0, 1.0]), np.pi / 2)
18
+ assert np.allclose(got, [[0.0, 1.0, 0.0]])
19
+
20
+ def test_points_on_the_axis_stay_put(self):
21
+ pts = np.array([[1.0, 2.0, 3.0], [1.0, 2.0, 5.0]])
22
+ got = _rotate_about_axis(pts, np.array([1.0, 2.0, 0.0]), np.array([0.0, 0.0, 2.0]), 1.234)
23
+ assert np.allclose(got, pts)
24
+
25
+ def test_axis_through_an_offset_point(self):
26
+ got = _rotate_about_axis(np.array([[2.0, 0.0, 0.0]]), np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 1.0]), np.pi)
27
+ assert np.allclose(got, [[0.0, 0.0, 0.0]])
28
+
29
+ def test_distances_are_preserved(self):
30
+ rng = np.random.default_rng(1)
31
+ pts = rng.normal(size=(6, 3))
32
+ got = _rotate_about_axis(pts, rng.normal(size=3), rng.normal(size=3), 0.7)
33
+ d0 = np.linalg.norm(pts[:, None] - pts[None], axis=2)
34
+ d1 = np.linalg.norm(got[:, None] - got[None], axis=2)
35
+ assert np.allclose(d0, d1)
36
+
37
+ def test_zero_turn_is_a_copy(self):
38
+ pts = np.ones((2, 3))
39
+ got = _rotate_about_axis(pts, np.zeros(3), np.array([1.0, 0.0, 0.0]), 0.0)
40
+ got[0, 0] = 9.0
41
+ assert pts[0, 0] == 1.0
42
+
43
+
44
+ class TestMinDistance:
45
+ def test_closest_pair(self):
46
+ a = np.array([[0.0, 0.0, 0.0], [5.0, 0.0, 0.0]])
47
+ b = np.array([[0.0, 3.0, 0.0], [5.0, 0.5, 0.0]])
48
+ assert _min_distance(a, b) == pytest.approx(0.5)
49
+
50
+ def test_empty_is_infinite(self):
51
+ assert _min_distance(np.empty((0, 3)), np.zeros((1, 3))) == np.inf
52
+
53
+
54
+ class TestTurnScanClearsAClash:
55
+ def test_the_best_turn_moves_a_substituent_off_an_occupied_site(self):
56
+ # one arm of a piece bonded along the z axis; a fixed atom sits where the arm points at 0 deg
57
+ piece = np.array([[0.15, 0.0, 0.35]])
58
+ fixed = np.array([[0.15, 0.0, 0.36]])
59
+ scores = []
60
+ for theta in np.deg2rad(np.arange(0, 360, 10)):
61
+ scores.append((_min_distance(_rotate_about_axis(piece, np.zeros(3), np.array([0, 0, 1.0]), theta), fixed),
62
+ theta))
63
+ best = max(scores)
64
+ assert scores[0][0] < 0.02
65
+ assert best[0] > 0.25
66
+ assert np.isclose(best[1], np.pi)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes