htpolynet 2.11.0__tar.gz → 2.11.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 (369) hide show
  1. {htpolynet-2.11.0 → htpolynet-2.11.2}/CHANGELOG.md +68 -0
  2. {htpolynet-2.11.0 → htpolynet-2.11.2}/PKG-INFO +1 -1
  3. {htpolynet-2.11.0 → htpolynet-2.11.2}/ROADMAP.md +66 -22
  4. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/htpolynetpackage.rst +5 -0
  5. {htpolynet-2.11.0 → htpolynet-2.11.2}/pyproject.toml +1 -1
  6. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/molecule.py +12 -1
  7. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/runtime.py +6 -1
  8. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/topocoord.py +5 -0
  9. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/topology.py +77 -0
  10. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/cure/ringcontroller.py +98 -7
  11. htpolynet-2.11.2/src/htpolynet/geometry/templategeom.py +267 -0
  12. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/schema/base.yaml +7 -0
  13. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_ringcontroller.py +136 -1
  14. htpolynet-2.11.2/tests/unit/test_templategeom.py +177 -0
  15. {htpolynet-2.11.0 → htpolynet-2.11.2}/.claude/settings.json +0 -0
  16. {htpolynet-2.11.0 → htpolynet-2.11.2}/.claude/skills/htpolynet/SKILL.md +0 -0
  17. {htpolynet-2.11.0 → htpolynet-2.11.2}/.envrc +0 -0
  18. {htpolynet-2.11.0 → htpolynet-2.11.2}/.github/workflows/conda-forge-sync.yml +0 -0
  19. {htpolynet-2.11.0 → htpolynet-2.11.2}/.github/workflows/docker.yml +0 -0
  20. {htpolynet-2.11.0 → htpolynet-2.11.2}/.github/workflows/docs.yml +0 -0
  21. {htpolynet-2.11.0 → htpolynet-2.11.2}/.github/workflows/release.yaml +0 -0
  22. {htpolynet-2.11.0 → htpolynet-2.11.2}/.github/workflows/test.yml +0 -0
  23. {htpolynet-2.11.0 → htpolynet-2.11.2}/.gitignore +0 -0
  24. {htpolynet-2.11.0 → htpolynet-2.11.2}/.readthedocs.yaml +0 -0
  25. {htpolynet-2.11.0 → htpolynet-2.11.2}/CITATION.cff +0 -0
  26. {htpolynet-2.11.0 → htpolynet-2.11.2}/CLAUDE.md +0 -0
  27. {htpolynet-2.11.0 → htpolynet-2.11.2}/LICENSE +0 -0
  28. {htpolynet-2.11.0 → htpolynet-2.11.2}/MANIFEST.in +0 -0
  29. {htpolynet-2.11.0 → htpolynet-2.11.2}/README.md +0 -0
  30. {htpolynet-2.11.0 → htpolynet-2.11.2}/docker/Dockerfile +0 -0
  31. {htpolynet-2.11.0 → htpolynet-2.11.2}/docker/compose.yml +0 -0
  32. {htpolynet-2.11.0 → htpolynet-2.11.2}/docker/docker-entrypoint.sh +0 -0
  33. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/Makefile +0 -0
  34. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/README.rst +0 -0
  35. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/make.bat +0 -0
  36. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/requirements.txt +0 -0
  37. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/_static/.gitkeep +0 -0
  38. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/_static/htpolynet-favicon.ico +0 -0
  39. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/_static/htpolynet-landing.jpg +0 -0
  40. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/_static/htpolynet-logo-dark.png +0 -0
  41. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/_static/htpolynet-logo-light.png +0 -0
  42. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/changelog.rst +0 -0
  43. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/conf.py +0 -0
  44. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +0 -0
  45. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/0-liquid-styrene/index.rst +0 -0
  46. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +0 -0
  47. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +0 -0
  48. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +0 -0
  49. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/0-liquid-styrene/results.rst +0 -0
  50. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/0-liquid-styrene/run.rst +0 -0
  51. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/configuration.rst +0 -0
  52. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/index.rst +0 -0
  53. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/introduction.rst +0 -0
  54. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/monomer.rst +0 -0
  55. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/STY.png +0 -0
  56. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/STYCC.png +0 -0
  57. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
  58. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
  59. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
  60. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
  61. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
  62. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +0 -0
  63. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
  64. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
  65. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
  66. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/pics/styrene-polymerization.png +0 -0
  67. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/postsim.rst +0 -0
  68. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/reactions.rst +0 -0
  69. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/results.rst +0 -0
  70. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/1-polystyrene/run.rst +0 -0
  71. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +0 -0
  72. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +0 -0
  73. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +0 -0
  74. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/BPA.png +0 -0
  75. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/GMA.png +0 -0
  76. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/HIE.png +0 -0
  77. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
  78. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
  79. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
  80. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.eps +0 -0
  81. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.fig +0 -0
  82. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.png +0 -0
  83. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +0 -0
  84. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
  85. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
  86. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
  87. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/p1-traces.png +0 -0
  88. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
  89. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.eps +0 -0
  90. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.fig +0 -0
  91. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.png +0 -0
  92. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +0 -0
  93. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +0 -0
  94. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +0 -0
  95. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +0 -0
  96. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +0 -0
  97. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +0 -0
  98. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +0 -0
  99. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +0 -0
  100. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-epoxy.png +0 -0
  101. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-labelled.png +0 -0
  102. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-2d.png +0 -0
  103. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-labelled.png +0 -0
  104. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
  105. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
  106. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
  107. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +0 -0
  108. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
  109. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
  110. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
  111. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.eps +0 -0
  112. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.fig +0 -0
  113. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.png +0 -0
  114. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/equil-rho_v_ns.png +0 -0
  115. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/postsim-typical.png +0 -0
  116. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-e.png +0 -0
  117. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-equil-rho_v_ns.png +0 -0
  118. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-rho_v_ns.png +0 -0
  119. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-tg.png +0 -0
  120. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r1.png +0 -0
  121. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r2.png +0 -0
  122. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r3.png +0 -0
  123. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
  124. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/rho_v_ns.png +0 -0
  125. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-e.png +0 -0
  126. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-tg.png +0 -0
  127. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +0 -0
  128. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +0 -0
  129. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +0 -0
  130. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +0 -0
  131. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +0 -0
  132. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +0 -0
  133. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +0 -0
  134. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +0 -0
  135. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
  136. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
  137. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
  138. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +0 -0
  139. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
  140. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
  141. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
  142. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
  143. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +0 -0
  144. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +0 -0
  145. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +0 -0
  146. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +0 -0
  147. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +0 -0
  148. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/index.rst +0 -0
  149. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +0 -0
  150. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +0 -0
  151. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
  152. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
  153. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
  154. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +0 -0
  155. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
  156. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
  157. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
  158. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
  159. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +0 -0
  160. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +0 -0
  161. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/results.rst +0 -0
  162. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/5-htpb-ipdi/run.rst +0 -0
  163. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +0 -0
  164. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/index.rst +0 -0
  165. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +0 -0
  166. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +0 -0
  167. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +0 -0
  168. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
  169. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
  170. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
  171. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
  172. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
  173. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
  174. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
  175. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +0 -0
  176. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +0 -0
  177. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/results.rst +0 -0
  178. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/6-cyanate-ester/run.rst +0 -0
  179. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/example-tutorials/index.rst +0 -0
  180. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/index.rst +0 -0
  181. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/install.rst +0 -0
  182. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/references/index.rst +0 -0
  183. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/references/mol2-reference.pdf +0 -0
  184. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/references.bib +0 -0
  185. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/CURE.odg +0 -0
  186. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/bond_filter.odg +0 -0
  187. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/building-a-system.rst +0 -0
  188. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
  189. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
  190. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/configs/configs-for-run.rst +0 -0
  191. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/configuration-files.rst +0 -0
  192. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/container-usage.rst +0 -0
  193. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/flow1.odg +0 -0
  194. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/flow1yaml.odg +0 -0
  195. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/hydrogenated.eps +0 -0
  196. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/hydrogenated.fig +0 -0
  197. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/index.rst +0 -0
  198. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/molecular-structure-inputs.rst +0 -0
  199. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/periodic-networks.rst +0 -0
  200. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/STY.png +0 -0
  201. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/STYCC.png +0 -0
  202. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
  203. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/bond_filter.png +0 -0
  204. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
  205. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
  206. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/hydrogenated.png +0 -0
  207. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
  208. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
  209. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/postcure-repair.rst +0 -0
  210. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/program-flow.rst +0 -0
  211. {htpolynet-2.11.0 → htpolynet-2.11.2}/docs/source/user-guide/usage.rst +0 -0
  212. {htpolynet-2.11.0 → htpolynet-2.11.2}/scripts/check-conda-sync.py +0 -0
  213. {htpolynet-2.11.0 → htpolynet-2.11.2}/scripts/release.sh +0 -0
  214. {htpolynet-2.11.0 → htpolynet-2.11.2}/scripts/render-detail.sh +0 -0
  215. {htpolynet-2.11.0 → htpolynet-2.11.2}/scripts/render-detail.tcl +0 -0
  216. {htpolynet-2.11.0 → htpolynet-2.11.2}/scripts/render-snapshot.sh +0 -0
  217. {htpolynet-2.11.0 → htpolynet-2.11.2}/scripts/run_all_examples.sh +0 -0
  218. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/__init__.py +0 -0
  219. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/analysis/__init__.py +0 -0
  220. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/analysis/analyze.py +0 -0
  221. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/analysis/plot.py +0 -0
  222. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/analysis/postsim.py +0 -0
  223. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/analysis/utils.py +0 -0
  224. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/cli.py +0 -0
  225. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/__init__.py +0 -0
  226. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/bondtemplate.py +0 -0
  227. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/configuration.py +0 -0
  228. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/coordinates.py +0 -0
  229. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/paramcache.py +0 -0
  230. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/productsplice.py +0 -0
  231. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/core/projectfilesystem.py +0 -0
  232. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/cure/__init__.py +0 -0
  233. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/cure/chain.py +0 -0
  234. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/cure/curecontroller.py +0 -0
  235. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/cure/expandreactions.py +0 -0
  236. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/cure/reaction.py +0 -0
  237. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/cure/triplesearch.py +0 -0
  238. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/external/__init__.py +0 -0
  239. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/external/ambertools.py +0 -0
  240. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/external/command.py +0 -0
  241. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/external/gromacs.py +0 -0
  242. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/external/slurm.py +0 -0
  243. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/external/smiles_input.py +0 -0
  244. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/external/software.py +0 -0
  245. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/geometry/__init__.py +0 -0
  246. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/geometry/bondlist.py +0 -0
  247. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/geometry/lattice.py +0 -0
  248. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/geometry/linkcell.py +0 -0
  249. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/geometry/matrix4.py +0 -0
  250. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/geometry/placement.py +0 -0
  251. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/geometry/ring.py +0 -0
  252. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/io/__init__.py +0 -0
  253. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/io/gro.py +0 -0
  254. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/io/mol2.py +0 -0
  255. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/io/pdb.py +0 -0
  256. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/repair/__init__.py +0 -0
  257. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/repair/cyanate_cap.py +0 -0
  258. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/repair/topology_surgery.py +0 -0
  259. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/README.md +0 -0
  260. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/__init__.py +0 -0
  261. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/claude/SKILL.md +0 -0
  262. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +0 -0
  263. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/example_depot/1-polystyrene.yaml +0 -0
  264. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +0 -0
  265. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +0 -0
  266. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +0 -0
  267. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +0 -0
  268. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +0 -0
  269. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/README.md +0 -0
  270. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
  271. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
  272. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
  273. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/min.mdp +0 -0
  274. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/npt.mdp +0 -0
  275. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
  276. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
  277. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
  278. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
  279. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
  280. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
  281. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
  282. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
  283. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
  284. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
  285. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
  286. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
  287. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/inputs/STY.mol2 +0 -0
  288. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
  289. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
  290. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
  291. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
  292. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
  293. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
  294. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
  295. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
  296. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
  297. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -0
  298. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
  299. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
  300. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
  301. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -0
  302. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -0
  303. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
  304. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
  305. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/resources/tcl/render.tcl +0 -0
  306. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/__init__.py +0 -0
  307. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/banner.py +0 -0
  308. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/checkpoint.py +0 -0
  309. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/convergence.py +0 -0
  310. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/dataframetools.py +0 -0
  311. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/inputcheck.py +0 -0
  312. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/logsetup.py +0 -0
  313. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/profiling.py +0 -0
  314. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/stringthings.py +0 -0
  315. {htpolynet-2.11.0 → htpolynet-2.11.2}/src/htpolynet/utils/vmd_viz.py +0 -0
  316. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/__init__.py +0 -0
  317. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/conftest.py +0 -0
  318. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/__init__.py +0 -0
  319. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/fixtures/config1.gro +0 -0
  320. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/fixtures/config1.top +0 -0
  321. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/fixtures/config2.gro +0 -0
  322. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/fixtures/config2.top +0 -0
  323. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/fixtures/items31.edr +0 -0
  324. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/fixtures/items43.edr +0 -0
  325. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/fixtures/items45.edr +0 -0
  326. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/fixtures/short.mdp +0 -0
  327. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_bondtemplate.py +0 -0
  328. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_cap_placement.py +0 -0
  329. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_chain.py +0 -0
  330. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_completion_bias.py +0 -0
  331. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_conda_sync.py +0 -0
  332. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_configuration.py +0 -0
  333. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_convergence.py +0 -0
  334. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_cure_site_functionality.py +0 -0
  335. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_dataframetools.py +0 -0
  336. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_density_gate.py +0 -0
  337. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_gpu_usability.py +0 -0
  338. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_gromacs_get_energy_menu.py +0 -0
  339. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_gromacs_gmx_energy_trace.py +0 -0
  340. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_inputcheck.py +0 -0
  341. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_linkcell_pierce.py +0 -0
  342. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_mdrun_gpu_options.py +0 -0
  343. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_mol2_bond_fallback.py +0 -0
  344. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_molecule_charge_report.py +0 -0
  345. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_moleculetype_name.py +0 -0
  346. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_multibody_reactions.py +0 -0
  347. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_paramcache.py +0 -0
  348. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_paramcache_ambertools.py +0 -0
  349. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_parameterize_react.py +0 -0
  350. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_placement_and_ringclose.py +0 -0
  351. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_plot_smoke.py +0 -0
  352. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_productsplice.py +0 -0
  353. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_projectfilesystem.py +0 -0
  354. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_relax_instrumentation.py +0 -0
  355. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_repair_charge_neutrality.py +0 -0
  356. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_repair_conversion.py +0 -0
  357. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_resources.py +0 -0
  358. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_ring.py +0 -0
  359. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_ring_pierce_figs.py +0 -0
  360. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_setup_claude.py +0 -0
  361. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_sibling_templates.py +0 -0
  362. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_slurm_script.py +0 -0
  363. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_smiles_input.py +0 -0
  364. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_software_provenance.py +0 -0
  365. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_topology/test.top +0 -0
  366. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_topology.py +0 -0
  367. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_transrot_turn_scan.py +0 -0
  368. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_triplesearch.py +0 -0
  369. {htpolynet-2.11.0 → htpolynet-2.11.2}/tests/unit/test_user_frcmod.py +0 -0
@@ -7,6 +7,74 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.11.2] - 2026-09-23
11
+
12
+ ### Fixed
13
+
14
+ - **A ring cure near its target kept re-proposing the triples it had just declined.**
15
+ Declining a ring that the closure ladder could not pull shut leaves its three groups
16
+ unreacted, which is the point -- but the next search then offered the same groups,
17
+ ran the same eight-stage ladder, and declined them again. htpolynet-study measured
18
+ the cost on a 2.11.1 build: at conversion 0.97 with 24 groups left, nine iterations
19
+ running produced 77 declines and not one ring, at about 67 s each.
20
+
21
+ A declined combination is now passed over while any untried ring is within the search
22
+ radius. It is a preference and not a prohibition: that cure escaped on iteration 41
23
+ and finished at 0.971, because the relaxation between iterations moves the groups, so
24
+ a triple that failed once can still close later. When the memory is the only thing
25
+ left keeping an iteration idle, the search lifts it and offers those rings again
26
+ rather than stand still.
27
+
28
+ ## [2.11.1] - 2026-09-22
29
+
30
+ ### Fixed
31
+
32
+ - **A cyclotrimerization's charges were computed on a ring that was never closed.** The
33
+ trimer template reached antechamber with its three ring bonds recorded but still about
34
+ 2.2 A long: the closure ladder cannot beat the reactants' own C#N, whose sp parameters
35
+ hold each group linear, and no force constant wins that. Charges come from the
36
+ geometry, so the semiempirical step charged three separate cyanates rather than a
37
+ triazine, leaving **every ring carbon about 0.21 e low** with the deficit smeared over
38
+ the rest of the molecule.
39
+
40
+ Nothing caught it. The atom types were right, because antechamber perceives those from
41
+ the connectivity, which was right; the molecules were neutral, because the error sums
42
+ to zero; and the system's own ring bonds relaxed to 1.347 A after the splice, because
43
+ the bonded parameters were fine. It surfaced only when htpolynet-study ran a campaign
44
+ with `bcc` charges and half their builds died in a 500 K anneal -- the release smoke
45
+ test had used `gas` charges, which are computed from the topology and could not have
46
+ seen it.
47
+
48
+ A product whose reaction closes a ring is now relaxed against its own connectivity
49
+ before it is parameterized, and refused if the ring is still open afterward.
50
+ Measured on a methyl cyanate trimer, ring-carbon charge: **+0.699 before, +0.909
51
+ after, against +0.909** for the same molecule built independently from SMILES.
52
+ htpolynet-study measured the same 0.21 e deficit on a bisphenol A dicyanate trimer.
53
+
54
+ Two things fell out of the investigation that are worth knowing:
55
+ - **Correcting the bond orders does not fix it.** An addition bond leaves the cyanate
56
+ carbon pentavalent -- it keeps its C#N, gains the ring bond, and still carries its
57
+ ester oxygen -- and that is now repaired too, since RDKit cannot read a molecule with
58
+ an impossible valence. But repairing the orders alone produced charges identical to
59
+ the broken ones, because the semiempirical step reads coordinates, not bond orders.
60
+ - **antechamber's output geometry is its input geometry.** It is not evidence about
61
+ what the charge calculation did or did not relax, and it should not be read as such.
62
+
63
+ - **A ring the closure ladder could not pull shut is now declined rather than bonded
64
+ long.** Late in a cure the matrix is rigid enough that a ring sometimes stops well
65
+ short -- one batch at conversion 0.95 ended 0.327 nm apart against a target of 0.150 --
66
+ and forming the bond anyway leaves it long for good: two ring bonds survived relaxation
67
+ and a 500 K anneal still 2.6 A apart, strained but stable, a defect the network then
68
+ carries permanently. Declining costs almost nothing, since the groups stay unreacted
69
+ and are offered again next iteration once the neighbourhood has moved. The limit is
70
+ `ring_cure: closure: max_accept`, default 0.30 nm; 0 restores the old behavior. Only
71
+ visible now because the charge fix let a build reach conversion 0.95 for the first
72
+ time.
73
+
74
+ - `Topology.rebalance_mol2_bond_orders` reduces a multiple bond when an addition would
75
+ otherwise leave an atom over-valent, preferring a bond that is over-valent at both ends
76
+ because reducing it repairs two atoms at once.
77
+
10
78
  ## [2.11.0] - 2026-09-22
11
79
 
12
80
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: htpolynet
3
- Version: 2.11.0
3
+ Version: 2.11.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,24 @@ Coverage as of the last measurement: **38.8%** overall.
199
199
 
200
200
  ## Cure and repair
201
201
 
202
+ - **A ring cure that stalls near its target has no exit but `max_iterations`.**
203
+ Reported by htpolynet-study 2026-09-23 from a 2.11.1 build: at conversion 0.97
204
+ with 24 groups left, nine iterations running (32-40) produced 77 declines and no
205
+ ring, about 67 s apiece. 2.11.1 now skips a triple it has already failed to
206
+ close, which removes most of that cost, but a cure with nothing closable left
207
+ still runs to `max_iterations` rather than stopping.
208
+
209
+ The obvious fix -- stop after N consecutive iterations that close nothing -- was
210
+ deliberately not taken, and the reason is worth keeping. That build escaped on
211
+ iteration 41 and finished at 0.971, and it was the one of four that survived the
212
+ study's postcure anneal. Any N below 9 would have ended it early. A stall is
213
+ not evidence that a cure is finished: the inter-iteration relaxation keeps moving
214
+ the groups, so the escape is real and can be a long time coming.
215
+
216
+ If this is revisited, the test should be something that distinguishes "nothing is
217
+ closable" from "nothing closed this time" -- the trend in the ladder's final
218
+ distances across the stalled run, say, rather than a count of iterations.
219
+
202
220
  - **Filtering candidate crosslinks against disallowed topologies, and what that means
203
221
  for cyanate esters.** Raised by Cameron 2026-09-21, who asked the right question:
204
222
  can "physically disallowable" even be defined for these systems? Partly. Three
@@ -265,6 +283,12 @@ Coverage as of the last measurement: **38.8%** overall.
265
283
  component, the test would reject every cycle-closing bond and no system could gel
266
284
  (ours carry a cycle rank of ~430 on ~938 junctions). Now noted in the code at
267
285
  both sites that read it, so it does not get "fixed".
286
+ - **Stronger than "could not gel": above 75% conversion an acyclic network does not
287
+ exist.** From the cycle-rank identity below, a forest (rank 0) requires
288
+ 4chi/3 - 1 = -(u+C)/n < 0, that is **chi < 3/4**. Our builds run to chi 0.97-0.99,
289
+ so cycle-closing bonds are *forced* there, not merely tolerated -- a test that
290
+ rejected them could not reach its own target conversion, never mind gel.
291
+ htpolynet-study, 2026-09-22, checked here.
268
292
 
269
293
  **Class 3, soft: strained cycles, and the threshold problem.** For cyanate esters
270
294
  this class is where a filter does *harm* if switched on -- see the end-group
@@ -292,7 +316,10 @@ Coverage as of the last measurement: **38.8%** overall.
292
316
  and the docs and the code comment must say why.** htpolynet-study, 2026-09-21,
293
317
  from the library: Fang & Shimp's end-group arithmetic caps acyclic dendritic
294
318
  growth at **75%** cyanate conversion, a mild ring-chain model at **90%**, and only
295
- severe macrocyclization reaches **98%**. Real cure reaches 98-99%, and Guenthner
319
+ severe macrocyclization reaches **98%**. That 75% is not only an end-group
320
+ argument: counting edges and vertices on the monomer-junction graph gives
321
+ chi < 3/4 for any acyclic network, with no chemistry in the derivation at all
322
+ (see the retraction below). Two independent routes to the same ceiling. Real cure reaches 98-99%, and Guenthner
296
323
  2014 treats the point as settled. **A 98% polycyanurate network cannot be
297
324
  macrocycle-free.** Filtering short cycles out of this chemistry would therefore
298
325
  remove the very structures that let it cure at all.
@@ -301,18 +328,34 @@ Coverage as of the last measurement: **38.8%** overall.
301
328
  are negligible. That justification inverts for cyanate esters. Put this in a
302
329
  comment where the filter is defined, because the filter will otherwise look
303
330
  under-used and someone will helpfully turn it on.
304
- - **If anything, we make too few.** Two independent measures: cycle rank per
305
- monomer **0.303 against Fang's 0.485**, and a gel-point delay of **+6.3% against
306
- Lin's +21%** cyclization term. So the interesting question for cyanate esters is
307
- not how to suppress cycles but why htpolynet produces fewer than the chemistry
308
- demands -- plausibly the 0.5 nm search radius and junctions seeded at t=0. That
309
- is a separate investigation, and the three-body reaction changes its terms, since
310
- junctions would then emerge where ends meet.
331
+ - **If anything, we make too few** -- on the gel-point evidence, which is now the
332
+ only evidence. A gel-point delay of **+6.3% against Lin's +21%** cyclization
333
+ term. So the interesting question for cyanate esters is not how to suppress
334
+ cycles but why htpolynet produces fewer than the chemistry demands -- plausibly
335
+ the 0.5 nm search radius and junctions seeded at t=0. That is a separate
336
+ investigation, and the three-body reaction changes its terms, since junctions
337
+ would then emerge where ends meet.
338
+ - **RETRACTED 2026-09-22: the cycle-rank half of that claim ("0.303 against Fang's
339
+ 0.485") was never a measurement.** On the monomer-junction graph, with
340
+ `same_residue: false` forbidding both arms of one monomer in one junction, the
341
+ edge count is fixed by the conversion: E = 3N and N = 2n*chi/3, so
342
+ cycle rank = E - V + C = n(4chi/3 - 1) + u + C, with u the monomers having no
343
+ reacted arm. Nothing about cyclization is left free. Raised by htpolynet-study
344
+ and checked here against an unrelated network -- 150 bisphenol A dicyanates at
345
+ chi 0.610 -- where the identity reproduces the measured rank of 2 with a residual
346
+ of zero to six decimals. Fang's 0.485 also cannot be a graph cycle rank at all:
347
+ 4chi/3 - 1 = 0.485 requires chi = 1.11. Two different quantities were being
348
+ compared. Do not reinstate the comparison; if a cyclization metric is wanted,
349
+ it has to be one with structural freedom left in it once chi is fixed -- the
350
+ cycle *spectrum* (how many cycles of each length) rather than the rank. The
351
+ freedom in the rank is exactly u + C, which for a well-cured network is about 1:
352
+ htpolynet-study measured rank 107 against a floor of 106.1 at n = 360, chi 0.971.
353
+ A metric whose entire range is one unit cannot separate two networks.
311
354
  - The 28-rings are near-unstrained in GAFF (span -0.07 A, C-O-C angle -0.46 deg
312
355
  against non-ring bridges), but that only says the force field tolerates them.
313
356
  Their absolute frequency is still set by our search radius and seeded junctions,
314
- so **1.4% must never be quoted as a physical cyclization rate**; the comparison
315
- against Fang above is the meaningful one.
357
+ so **1.4% must never be quoted as a physical cyclization rate**; the gel-point
358
+ comparison above is the meaningful one, the cycle-rank one having been retracted.
316
359
  - **Do not validate the filter on Tg in this system -- it is underpowered, and
317
360
  that is bounded, not guessed.** Between-bridge spread in ring density is 0.67
318
361
  percentage points of bridges, and dTg/dconversion averages 5.6 K per percentage
@@ -1738,15 +1781,16 @@ Coverage as of the last measurement: **38.8%** overall.
1738
1781
  structure-property story.
1739
1782
 
1740
1783
 
1741
- - **A ring-closing ladder stops around 0.22 nm, not at its 0.15 nm target.**
1742
- The closure restraints pull three cyanate groups together before any ring bond
1743
- exists, and they consistently stall at ~0.225 nm regardless of how far apart
1744
- they started -- in the isolated trimer template too, so it is not crowding by
1745
- the surrounding system. The cause is that the groups still carry their
1746
- sp-hybridized C#N parameters while being pulled, and a linear triple bond
1747
- resists closing the angle a triazine needs; no force constant fixes that. It
1748
- is benign today: the bonds are formed at that length, the template splice
1749
- replaces the types, and the relax step brings them to 1.35 A, which every
1750
- build has confirmed. The warning threshold (twice the target) has never
1751
- fired. If it ever does, the fix is to attenuate the C#N bonded parameters
1752
- along the closure ladder rather than to pull harder.
1784
+ - **Every template is parameterized with its new bonds still about 2.2 A long, and
1785
+ whether that matters outside ring closures is unverified.** htpolynet records a
1786
+ reaction's bonds and only relaxes the geometry after parameterization, so antechamber
1787
+ always sees a product whose new bonds are stretched -- a styrene dimer as much as a
1788
+ triazine. For ring closures this was measured to be badly wrong (0.21 e per ring
1789
+ carbon; see the CHANGELOG for 2.11.1) and is now fixed by relaxing those templates
1790
+ first. For an ordinary one-bond condensation nobody has checked. The honest test is
1791
+ not the output mol2, because antechamber echoes its input coordinates into it: it is
1792
+ to parameterize a dimer template both as built and after relaxing it, and compare the
1793
+ charges near the new bond. If they differ materially, the same relaxation should be
1794
+ applied to every product, which would move the charges of every template htpolynet has
1795
+ ever built -- so it wants measuring before it is done, and a deliberate decision about
1796
+ reproducibility against published results.
@@ -202,6 +202,11 @@ htpolynet.geometry
202
202
  :undoc-members:
203
203
  :show-inheritance:
204
204
 
205
+ .. automodule:: htpolynet.geometry.templategeom
206
+ :members:
207
+ :undoc-members:
208
+ :show-inheritance:
209
+
205
210
  htpolynet.repair
206
211
  ----------------
207
212
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "htpolynet"
7
- version = "2.11.0"
7
+ version = "2.11.2"
8
8
  authors = [
9
9
  { name="Cameron F Abrams", email="cfa22@drexel.edu" },
10
10
  ]
@@ -18,11 +18,13 @@ from ..core.bondtemplate import BondTemplate, BondTemplateList, ReactionBond, Re
18
18
  from ..core.topocoord import TopoCoord
19
19
  from ..cure.chain import ChainManager
20
20
  from ..cure.reaction import (Reaction, ReactionList, consumes_sacrificial_h, reaction_stage,
21
- spanning_and_closing_bonds)
21
+ spanning_and_closing_bonds, is_ring_closing)
22
22
  from ..external.ambertools import GAFFParameterize
23
23
  from ..external.command import run
24
24
  from ..external.gromacs import mdp_modify,gro_from_trr
25
25
  from ..geometry.matrix4 import Matrix4
26
+ from ..geometry.templategeom import (check_ring_closed,
27
+ relax_geometry as relax_template_geometry)
26
28
  from ..geometry.placement import min_distance, place_group, rotate_about_axis
27
29
  from ..io.gro import GRX_ATTRIBUTES
28
30
 
@@ -510,6 +512,15 @@ class Molecule:
510
512
  # logger.debug(f'Using override input molecules/inputs/{self.name}.{isf} as a generator')
511
513
  # pfs.checkout(f'molecules/inputs/{self.name}.{isf}')
512
514
  # else:
515
+ # A ring closure leaves the template's coordinates describing its reactants
516
+ # rather than its product: the closure ladder cannot beat the reactants' own
517
+ # sp parameters, so the ring bonds are recorded but still ~0.22 nm long.
518
+ # Charges are computed from the geometry, so this has to be put right before
519
+ # antechamber sees it -- see geometry.templategeom.
520
+ if is_ring_closing(R):
521
+ self.TopoCoord.Topology.rebalance_mol2_bond_orders()
522
+ relax_template_geometry(self.TopoCoord, name=self.name)
523
+ check_ring_closed(self.TopoCoord, self.name)
513
524
  self.TopoCoord.write_mol2(filename=f'{self.name}.mol2', molname=self.name)
514
525
  if not do_parameterization:
515
526
  self.TopoCoord.write_gro(f'{self.name}.gro', grotitle=self.name)
@@ -701,7 +701,12 @@ class Runtime:
701
701
  rc.state.iter += 1
702
702
  continue
703
703
  bdf = triple_bonds_dataframe(chosen, sites, R.product, order=R.bonds[0].get('order', 1))
704
- rc.close_rings(TC, bdf, gromacs_dict=gromacs_dict)
704
+ work = rc.close_rings(TC, bdf, gromacs_dict=gromacs_dict)
705
+ # a ring the ladder could not pull shut would be bonded long and stay that way
706
+ bdf, chosen = rc.accept(bdf, work, chosen)
707
+ if not chosen:
708
+ rc.state.iter += 1
709
+ continue
705
710
  rc.form_rings(TC, bdf, sites, chosen, template, template_resids,
706
711
  name_translations=name_translations, atom_names=arm)
707
712
  rc.relax(TC, gromacs_dict=gromacs_dict)
@@ -1307,6 +1307,11 @@ class TopoCoord:
1307
1307
  # htpolynet-study 2026-09-21: that is the sole reason no cured cyanate-ester
1308
1308
  # network in 96 cells contains an intramolecular 14-ring, while carrying a
1309
1309
  # cycle rank of ~430 on ~938 junctions. Do not "fix" the staleness.
1310
+ # Nor is gelling the whole of it: counting edges and vertices on the
1311
+ # monomer-junction graph, an acyclic network requires a conversion below
1312
+ # 3/4, so above that every further bond MUST close a cycle. A cure that
1313
+ # refused cycle-closing bonds could not reach the conversions this
1314
+ # chemistry is run at (0.97-0.99) at all.
1310
1315
  assert i_resNum!=j_resNum,f'shortcircuit test error {i}-{j} both in residue {i_resNum}?'
1311
1316
  i_neighbors=self.Topology.bondlist.partners_of(i)
1312
1317
  j_neighbors=self.Topology.bondlist.partners_of(j)
@@ -209,6 +209,23 @@ def select_topology_type_option(options, typename='dihedraltypes', rule='stiffes
209
209
  return sorted_options[0]
210
210
  return []
211
211
 
212
+
213
+ def _element_of(name, gafftype):
214
+ """Best guess at an atom's element from its GAFF type, falling back to its name.
215
+
216
+ GAFF types are lowercase element-led (``ca``, ``nb``, ``os``, ``hc``), with the
217
+ two-letter halogens the only ambiguity worth handling.
218
+ """
219
+ for src in (str(gafftype), str(name)):
220
+ t = src.strip().upper()
221
+ if not t:
222
+ continue
223
+ if t[:2] in ('CL', 'BR'):
224
+ return t[:2]
225
+ if t[0].isalpha():
226
+ return t[0]
227
+ return ''
228
+
212
229
  class Topology:
213
230
  """ Class for handling gromacs topology data
214
231
  """
@@ -649,6 +666,66 @@ class Topology:
649
666
  to_drop.append(d[(d.ai == ai) & (d.aj == aj)].index.values[0])
650
667
  self.D['bonds'] = self.D['bonds'].drop(to_drop)
651
668
 
669
+ def rebalance_mol2_bond_orders(self, atoms=None):
670
+ """Restores valence after an addition bond, by reducing a multiple bond.
671
+
672
+ A condensation reaction removes a hydrogen from each atom it bonds, so valence
673
+ takes care of itself. An addition removes nothing: ``add_bonds`` records the new
674
+ mol2 bond at order 1 and leaves every existing bond alone, so an atom that already
675
+ carried a multiple bond ends up over-valent. A cyclotrimerization does exactly
676
+ this -- the cyanate carbon keeps its C#N, gains the ring bond, and still carries
677
+ its ester oxygen, for a valence of five.
678
+
679
+ The mol2 bond orders are what antechamber perceives the molecule from, so an
680
+ impossible valence there is not cosmetic. Reducing the shared triple bond fixes
681
+ both of its atoms at once, which is why a bond over-valent at BOTH ends is chosen
682
+ first.
683
+
684
+ Args:
685
+ atoms (iterable): restrict the repair to these atom numbers, normally the ones
686
+ a reaction just bonded; None considers every atom
687
+
688
+ Returns:
689
+ int: how many bond orders were reduced
690
+ """
691
+ mb = self.D.get('mol2_bonds')
692
+ if mb is None or mb.empty:
693
+ return 0
694
+ at = self.D['atoms']
695
+ element = {int(r.nr): _element_of(r.atom, r.type) for r in at.itertuples()}
696
+ limit = {'H': 1, 'C': 4, 'N': 3, 'O': 2, 'F': 1, 'CL': 1, 'BR': 1, 'I': 1}
697
+ order_of = {'1': 1.0, '2': 2.0, '3': 3.0, 'ar': 1.5, 'am': 1.0}
698
+ watch = None if atoms is None else {int(a) for a in atoms}
699
+ reduced = 0
700
+ for _ in range(4 * mb.shape[0]): # each pass reduces one order; bounded
701
+ val = {}
702
+ for r in mb.itertuples():
703
+ o = order_of.get(str(r.order), 1.0)
704
+ val[int(r.ai)] = val.get(int(r.ai), 0.0) + o
705
+ val[int(r.aj)] = val.get(int(r.aj), 0.0) + o
706
+ over = {a: v - limit[element[a]] for a, v in val.items()
707
+ if element.get(a) in limit and v > limit[element[a]] + 0.01
708
+ and (watch is None or a in watch)}
709
+ if not over:
710
+ break
711
+ # a bond over-valent at both ends repairs two atoms at once
712
+ cand = [(i, r) for i, r in enumerate(mb.itertuples())
713
+ if order_of.get(str(r.order), 1.0) >= 2.0
714
+ and (int(r.ai) in over or int(r.aj) in over)]
715
+ if not cand:
716
+ break
717
+ cand.sort(key=lambda x: (-(int(x[1].ai) in over) - (int(x[1].aj) in over),
718
+ -order_of.get(str(x[1].order), 1.0)))
719
+ i, row = cand[0]
720
+ newo = int(order_of[str(row.order)] - 1)
721
+ mb.iat[i, mb.columns.get_loc('order')] = str(newo)
722
+ logger.debug(f'valence repair: bond {row.ai}-{row.aj} order '
723
+ f'{row.order} -> {newo}')
724
+ reduced += 1
725
+ if reduced:
726
+ logger.info(f'Reduced {reduced} bond order(s) to keep valence after an addition')
727
+ return reduced
728
+
652
729
  def add_bonds(self, pairs=[]):
653
730
  """Adds bonds indicated in list pairs to the topology.
654
731
 
@@ -33,6 +33,21 @@ from ..repair.topology_surgery import neutralize_touched_fragments
33
33
  logger = logging.getLogger(__name__)
34
34
 
35
35
 
36
+ def _triple_key(donors):
37
+ """A ring's identity, in terms that survive from one iteration to the next.
38
+
39
+ A triple is held as row numbers into the site table, and that table is rebuilt
40
+ every iteration and shrinks as groups react, so those numbers name a different
41
+ ring next time. The three donor atoms do not move: one per group, unique to it,
42
+ and fixed for the life of the system.
43
+
44
+ The two ring orientations deliberately share a key. :func:`candidate_triples`
45
+ scores both and keeps the better one, so the orientation that was declined is the
46
+ better one, and the other would have farther to go.
47
+ """
48
+ return frozenset(int(d) for d in donors)
49
+
50
+
36
51
  class RingCureState:
37
52
  """How far a ring cure has got, and enough to resume it."""
38
53
 
@@ -81,7 +96,7 @@ class RingController:
81
96
  'same_residue': False,
82
97
  'relax': [{'ensemble': 'min'},
83
98
  {'ensemble': 'nvt', 'temperature': 300, 'nsteps': 2000}],
84
- 'closure': {'nstages': 8, 'target': 0.15, 'kb': 300000.0,
99
+ 'closure': {'nstages': 8, 'target': 0.15, 'kb': 300000.0, 'max_accept': 0.30,
85
100
  'equilibration': [{'ensemble': 'min'},
86
101
  {'ensemble': 'nvt', 'temperature': 600, 'nsteps': 1000}]},
87
102
  }
@@ -93,6 +108,7 @@ class RingController:
93
108
  self.dicts = d
94
109
  self.state = state or RingCureState()
95
110
  self.rings_df = None
111
+ self.declined = set()
96
112
 
97
113
  # ---- what the loop decides, all of it testable without MD ----
98
114
 
@@ -172,16 +188,49 @@ class RingController:
172
188
  cands = candidate_triples(sites, positions, self.radius, box,
173
189
  same_molecule=self.dicts['same_molecule'],
174
190
  same_residue=self.dicts['same_residue'])
175
- chosen = select_disjoint(cands, max_triples=self.dicts['max_rings_per_iteration'])
191
+ allowed = self._drop_declined(cands, sites)
192
+ chosen = select_disjoint(allowed, max_triples=self.dicts['max_rings_per_iteration'])
193
+ passed = len(cands) - len(allowed)
176
194
  logger.info(f'Iteration {self.state.iter}: {len(sites)} unreacted group(s), '
177
- f'{len(cands)} candidate ring(s) within {self.radius:.3f} nm, '
178
- f'{len(chosen)} accepted')
195
+ f'{len(cands)} candidate ring(s) within {self.radius:.3f} nm'
196
+ + (f' ({passed} passed over as already failed)' if passed else '')
197
+ + f', {len(chosen)} accepted')
179
198
  if len(chosen) >= floor or self.radius >= self.dicts['max_radius']:
199
+ if not chosen and cands and self.declined:
200
+ # the memory is now the only thing keeping this iteration idle, and
201
+ # the groups have moved since they were declined; try them again
202
+ logger.info(f'Iteration {self.state.iter}: every ring in reach has '
203
+ f'failed before; forgetting {len(self.declined)} of them '
204
+ f'and offering them again')
205
+ self.declined.clear()
206
+ chosen = select_disjoint(cands,
207
+ max_triples=self.dicts['max_rings_per_iteration'])
180
208
  return sites, chosen
181
209
  self.state.radius_index += 1
182
210
  logger.info(f'Radius increased to {self.radius:.3f} nm '
183
211
  f'({len(chosen)}/{floor} ring(s) so far)')
184
212
 
213
+ def _drop_declined(self, cands, sites):
214
+ """Passes over the triples this cure has already failed to pull shut.
215
+
216
+ A declined ring leaves its three groups unreacted by design, and the next search
217
+ offers them again -- so a rigid endgame proposes the same triples, runs the same
218
+ closure ladder, and declines them again. Measured at conversion 0.97 with 24
219
+ groups left: nine iterations running, 77 declines, about 67 s apiece, before one
220
+ triple finally closed and the cure finished at 0.971.
221
+
222
+ A preference, not a prohibition, because the geometry between one decline and the
223
+ next search is not identical -- the inter-iteration relaxation moves the groups,
224
+ which is how that cure escaped. Skipping a triple saves a ladder that would
225
+ almost certainly fail; refusing it outright would have ended that cure three
226
+ iterations early. :meth:`search` therefore lifts the whole memory rather than
227
+ come back empty-handed.
228
+ """
229
+ if not self.declined:
230
+ return cands
231
+ return [c for c in cands
232
+ if _triple_key(sites.at[a, 'donor'] for a in c[1]) not in self.declined]
233
+
185
234
  def record(self, chosen):
186
235
  """Counts the rings formed and the groups they consumed."""
187
236
  self.state.rings += len(chosen)
@@ -229,11 +278,53 @@ class RingController:
229
278
  TC.add_length_attribute(work, attr_name='final_distance')
230
279
  worst = work['final_distance'].max()
231
280
  logger.info(f'Rings closed to at most {worst:.3f} nm (target {c["target"]:.3f})')
232
- if worst > 2.0 * c['target']:
233
- logger.warning(f'A ring-closing pair is still {worst:.3f} nm apart; its bond will be '
234
- f'formed long and relaxed, which may strain the network')
235
281
  return work
236
282
 
283
+ def accept(self, bdf, work, chosen):
284
+ """Drops any ring the closure ladder could not actually pull shut.
285
+
286
+ Late in a cure the matrix is rigid enough that a ring sometimes stops well short
287
+ -- one batch at conversion 0.95 ended 0.327 nm apart against a target of 0.150.
288
+ Forming the bond anyway leaves it long: two ring bonds survived relaxation and a
289
+ 500 K anneal still 2.6 A apart, strained but stable, which is a defect the
290
+ network then carries for good.
291
+
292
+ Declining costs almost nothing. The groups stay unreacted and are offered again
293
+ next iteration, by which time the neighbourhood has moved; only if they can never
294
+ close does the cure lose them, which is the right outcome.
295
+
296
+ The combination itself is recorded for :meth:`_drop_declined`, which prefers not
297
+ to spend another ladder on it while any untried ring is in reach. That is what
298
+ a rigid endgame otherwise does: nine iterations running, 77 declines, the same
299
+ few triples every time.
300
+
301
+ Args:
302
+ bdf (pandas.DataFrame): this iteration's bonds, three rows per ring
303
+ work (pandas.DataFrame): the same pairs with their final distances
304
+ chosen (list): the rings the search accepted
305
+
306
+ Returns:
307
+ tuple: (bdf, chosen) keeping only the rings that closed
308
+ """
309
+ limit = self.dicts['closure']['max_accept']
310
+ if not limit:
311
+ return bdf, chosen
312
+ worst = work['final_distance'].to_numpy().reshape(-1, 3).max(axis=1)
313
+ keep = [n for n in range(len(chosen)) if worst[n] <= limit]
314
+ if len(keep) == len(chosen):
315
+ return bdf, chosen
316
+ for n in range(len(chosen)):
317
+ if n not in keep:
318
+ self.declined.add(_triple_key(bdf[bdf['triple'] == n]['ai']))
319
+ logger.info(f'Iteration {self.state.iter}: declining a ring still '
320
+ f'{worst[n]:.3f} nm from closing (limit {limit:.3f} nm); its '
321
+ f'groups stay unreacted, and this combination waits until '
322
+ f'nothing untried is in reach')
323
+ renumber = {old: new for new, old in enumerate(keep)}
324
+ bdf = bdf[bdf['triple'].isin(keep)].copy()
325
+ bdf['triple'] = [renumber[t] for t in bdf['triple']]
326
+ return bdf.reset_index(drop=True), [chosen[n] for n in keep]
327
+
237
328
  def relax(self, TC, gromacs_dict=None):
238
329
  """Eases a freshly closed ring's bonds in before anything else runs.
239
330