mlmm-toolkit 0.2.2.dev0__py3-none-any.whl

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 (372) hide show
  1. hessian_ff/__init__.py +50 -0
  2. hessian_ff/analytical_hessian.py +609 -0
  3. hessian_ff/constants.py +46 -0
  4. hessian_ff/forcefield.py +339 -0
  5. hessian_ff/loaders.py +608 -0
  6. hessian_ff/native/Makefile +8 -0
  7. hessian_ff/native/__init__.py +28 -0
  8. hessian_ff/native/analytical_hessian.py +88 -0
  9. hessian_ff/native/analytical_hessian_ext.cpp +258 -0
  10. hessian_ff/native/bonded.py +82 -0
  11. hessian_ff/native/bonded_ext.cpp +640 -0
  12. hessian_ff/native/loader.py +349 -0
  13. hessian_ff/native/nonbonded.py +118 -0
  14. hessian_ff/native/nonbonded_ext.cpp +1150 -0
  15. hessian_ff/prmtop_parmed.py +23 -0
  16. hessian_ff/system.py +107 -0
  17. hessian_ff/terms/__init__.py +14 -0
  18. hessian_ff/terms/angle.py +73 -0
  19. hessian_ff/terms/bond.py +44 -0
  20. hessian_ff/terms/cmap.py +406 -0
  21. hessian_ff/terms/dihedral.py +141 -0
  22. hessian_ff/terms/nonbonded.py +209 -0
  23. hessian_ff/tests/__init__.py +0 -0
  24. hessian_ff/tests/conftest.py +75 -0
  25. hessian_ff/tests/data/small/complex.parm7 +1346 -0
  26. hessian_ff/tests/data/small/complex.pdb +125 -0
  27. hessian_ff/tests/data/small/complex.rst7 +63 -0
  28. hessian_ff/tests/test_coords_input.py +44 -0
  29. hessian_ff/tests/test_energy_force.py +49 -0
  30. hessian_ff/tests/test_hessian.py +137 -0
  31. hessian_ff/tests/test_smoke.py +18 -0
  32. hessian_ff/tests/test_validation.py +40 -0
  33. hessian_ff/workflows.py +889 -0
  34. mlmm/__init__.py +36 -0
  35. mlmm/__main__.py +7 -0
  36. mlmm/_version.py +34 -0
  37. mlmm/add_elem_info.py +374 -0
  38. mlmm/advanced_help.py +91 -0
  39. mlmm/align_freeze_atoms.py +601 -0
  40. mlmm/all.py +3535 -0
  41. mlmm/bond_changes.py +231 -0
  42. mlmm/bool_compat.py +223 -0
  43. mlmm/cli.py +574 -0
  44. mlmm/cli_utils.py +166 -0
  45. mlmm/default_group.py +337 -0
  46. mlmm/defaults.py +467 -0
  47. mlmm/define_layer.py +526 -0
  48. mlmm/dft.py +1041 -0
  49. mlmm/energy_diagram.py +253 -0
  50. mlmm/extract.py +2213 -0
  51. mlmm/fix_altloc.py +464 -0
  52. mlmm/freq.py +1406 -0
  53. mlmm/harmonic_constraints.py +140 -0
  54. mlmm/hessian_cache.py +44 -0
  55. mlmm/hessian_calc.py +174 -0
  56. mlmm/irc.py +638 -0
  57. mlmm/mlmm_calc.py +2262 -0
  58. mlmm/mm_parm.py +945 -0
  59. mlmm/oniom_export.py +1983 -0
  60. mlmm/oniom_import.py +457 -0
  61. mlmm/opt.py +1742 -0
  62. mlmm/path_opt.py +1353 -0
  63. mlmm/path_search.py +2299 -0
  64. mlmm/preflight.py +88 -0
  65. mlmm/py.typed +1 -0
  66. mlmm/pysis_runner.py +45 -0
  67. mlmm/scan.py +1047 -0
  68. mlmm/scan2d.py +1226 -0
  69. mlmm/scan3d.py +1265 -0
  70. mlmm/scan_common.py +184 -0
  71. mlmm/summary_log.py +736 -0
  72. mlmm/trj2fig.py +448 -0
  73. mlmm/tsopt.py +2871 -0
  74. mlmm/utils.py +2309 -0
  75. mlmm/xtb_embedcharge_correction.py +475 -0
  76. mlmm_toolkit-0.2.2.dev0.dist-info/METADATA +1159 -0
  77. mlmm_toolkit-0.2.2.dev0.dist-info/RECORD +372 -0
  78. mlmm_toolkit-0.2.2.dev0.dist-info/WHEEL +5 -0
  79. mlmm_toolkit-0.2.2.dev0.dist-info/entry_points.txt +2 -0
  80. mlmm_toolkit-0.2.2.dev0.dist-info/licenses/LICENSE +674 -0
  81. mlmm_toolkit-0.2.2.dev0.dist-info/top_level.txt +4 -0
  82. pysisyphus/Geometry.py +1667 -0
  83. pysisyphus/LICENSE +674 -0
  84. pysisyphus/TableFormatter.py +63 -0
  85. pysisyphus/TablePrinter.py +74 -0
  86. pysisyphus/__init__.py +12 -0
  87. pysisyphus/calculators/AFIR.py +452 -0
  88. pysisyphus/calculators/AnaPot.py +20 -0
  89. pysisyphus/calculators/AnaPot2.py +48 -0
  90. pysisyphus/calculators/AnaPot3.py +12 -0
  91. pysisyphus/calculators/AnaPot4.py +20 -0
  92. pysisyphus/calculators/AnaPotBase.py +337 -0
  93. pysisyphus/calculators/AnaPotCBM.py +25 -0
  94. pysisyphus/calculators/AtomAtomTransTorque.py +154 -0
  95. pysisyphus/calculators/CFOUR.py +250 -0
  96. pysisyphus/calculators/Calculator.py +844 -0
  97. pysisyphus/calculators/CerjanMiller.py +24 -0
  98. pysisyphus/calculators/Composite.py +123 -0
  99. pysisyphus/calculators/ConicalIntersection.py +171 -0
  100. pysisyphus/calculators/DFTBp.py +430 -0
  101. pysisyphus/calculators/DFTD3.py +66 -0
  102. pysisyphus/calculators/DFTD4.py +84 -0
  103. pysisyphus/calculators/Dalton.py +61 -0
  104. pysisyphus/calculators/Dimer.py +681 -0
  105. pysisyphus/calculators/Dummy.py +20 -0
  106. pysisyphus/calculators/EGO.py +76 -0
  107. pysisyphus/calculators/EnergyMin.py +224 -0
  108. pysisyphus/calculators/ExternalPotential.py +264 -0
  109. pysisyphus/calculators/FakeASE.py +35 -0
  110. pysisyphus/calculators/FourWellAnaPot.py +28 -0
  111. pysisyphus/calculators/FreeEndNEBPot.py +39 -0
  112. pysisyphus/calculators/Gaussian09.py +18 -0
  113. pysisyphus/calculators/Gaussian16.py +726 -0
  114. pysisyphus/calculators/HardSphere.py +159 -0
  115. pysisyphus/calculators/IDPPCalculator.py +49 -0
  116. pysisyphus/calculators/IPIClient.py +133 -0
  117. pysisyphus/calculators/IPIServer.py +234 -0
  118. pysisyphus/calculators/LEPSBase.py +24 -0
  119. pysisyphus/calculators/LEPSExpr.py +139 -0
  120. pysisyphus/calculators/LennardJones.py +80 -0
  121. pysisyphus/calculators/MOPAC.py +219 -0
  122. pysisyphus/calculators/MullerBrownSympyPot.py +51 -0
  123. pysisyphus/calculators/MultiCalc.py +85 -0
  124. pysisyphus/calculators/NFK.py +45 -0
  125. pysisyphus/calculators/OBabel.py +87 -0
  126. pysisyphus/calculators/ONIOMv2.py +1129 -0
  127. pysisyphus/calculators/ORCA.py +893 -0
  128. pysisyphus/calculators/ORCA5.py +6 -0
  129. pysisyphus/calculators/OpenMM.py +88 -0
  130. pysisyphus/calculators/OpenMolcas.py +281 -0
  131. pysisyphus/calculators/OverlapCalculator.py +908 -0
  132. pysisyphus/calculators/Psi4.py +218 -0
  133. pysisyphus/calculators/PyPsi4.py +37 -0
  134. pysisyphus/calculators/PySCF.py +341 -0
  135. pysisyphus/calculators/PyXTB.py +73 -0
  136. pysisyphus/calculators/QCEngine.py +106 -0
  137. pysisyphus/calculators/Rastrigin.py +22 -0
  138. pysisyphus/calculators/Remote.py +76 -0
  139. pysisyphus/calculators/Rosenbrock.py +15 -0
  140. pysisyphus/calculators/SocketCalc.py +97 -0
  141. pysisyphus/calculators/TIP3P.py +111 -0
  142. pysisyphus/calculators/TransTorque.py +161 -0
  143. pysisyphus/calculators/Turbomole.py +965 -0
  144. pysisyphus/calculators/VRIPot.py +37 -0
  145. pysisyphus/calculators/WFOWrapper.py +333 -0
  146. pysisyphus/calculators/WFOWrapper2.py +341 -0
  147. pysisyphus/calculators/XTB.py +418 -0
  148. pysisyphus/calculators/__init__.py +81 -0
  149. pysisyphus/calculators/cosmo_data.py +139 -0
  150. pysisyphus/calculators/parser.py +150 -0
  151. pysisyphus/color.py +19 -0
  152. pysisyphus/config.py +133 -0
  153. pysisyphus/constants.py +65 -0
  154. pysisyphus/cos/AdaptiveNEB.py +230 -0
  155. pysisyphus/cos/ChainOfStates.py +725 -0
  156. pysisyphus/cos/FreeEndNEB.py +25 -0
  157. pysisyphus/cos/FreezingString.py +103 -0
  158. pysisyphus/cos/GrowingChainOfStates.py +71 -0
  159. pysisyphus/cos/GrowingNT.py +309 -0
  160. pysisyphus/cos/GrowingString.py +508 -0
  161. pysisyphus/cos/NEB.py +189 -0
  162. pysisyphus/cos/SimpleZTS.py +64 -0
  163. pysisyphus/cos/__init__.py +22 -0
  164. pysisyphus/cos/stiffness.py +199 -0
  165. pysisyphus/drivers/__init__.py +17 -0
  166. pysisyphus/drivers/afir.py +855 -0
  167. pysisyphus/drivers/barriers.py +271 -0
  168. pysisyphus/drivers/birkholz.py +138 -0
  169. pysisyphus/drivers/cluster.py +318 -0
  170. pysisyphus/drivers/diabatization.py +133 -0
  171. pysisyphus/drivers/merge.py +368 -0
  172. pysisyphus/drivers/merge_mol2.py +322 -0
  173. pysisyphus/drivers/opt.py +375 -0
  174. pysisyphus/drivers/perf.py +91 -0
  175. pysisyphus/drivers/pka.py +52 -0
  176. pysisyphus/drivers/precon_pos_rot.py +669 -0
  177. pysisyphus/drivers/rates.py +480 -0
  178. pysisyphus/drivers/replace.py +219 -0
  179. pysisyphus/drivers/scan.py +212 -0
  180. pysisyphus/drivers/spectrum.py +166 -0
  181. pysisyphus/drivers/thermo.py +31 -0
  182. pysisyphus/dynamics/Gaussian.py +103 -0
  183. pysisyphus/dynamics/__init__.py +20 -0
  184. pysisyphus/dynamics/colvars.py +136 -0
  185. pysisyphus/dynamics/driver.py +297 -0
  186. pysisyphus/dynamics/helpers.py +256 -0
  187. pysisyphus/dynamics/lincs.py +105 -0
  188. pysisyphus/dynamics/mdp.py +364 -0
  189. pysisyphus/dynamics/rattle.py +121 -0
  190. pysisyphus/dynamics/thermostats.py +128 -0
  191. pysisyphus/dynamics/wigner.py +266 -0
  192. pysisyphus/elem_data.py +3473 -0
  193. pysisyphus/exceptions.py +2 -0
  194. pysisyphus/filtertrj.py +69 -0
  195. pysisyphus/helpers.py +623 -0
  196. pysisyphus/helpers_pure.py +649 -0
  197. pysisyphus/init_logging.py +50 -0
  198. pysisyphus/intcoords/Bend.py +69 -0
  199. pysisyphus/intcoords/Bend2.py +25 -0
  200. pysisyphus/intcoords/BondedFragment.py +32 -0
  201. pysisyphus/intcoords/Cartesian.py +41 -0
  202. pysisyphus/intcoords/CartesianCoords.py +140 -0
  203. pysisyphus/intcoords/Coords.py +56 -0
  204. pysisyphus/intcoords/DLC.py +197 -0
  205. pysisyphus/intcoords/DistanceFunction.py +34 -0
  206. pysisyphus/intcoords/DummyImproper.py +70 -0
  207. pysisyphus/intcoords/DummyTorsion.py +72 -0
  208. pysisyphus/intcoords/LinearBend.py +105 -0
  209. pysisyphus/intcoords/LinearDisplacement.py +80 -0
  210. pysisyphus/intcoords/OutOfPlane.py +59 -0
  211. pysisyphus/intcoords/PrimTypes.py +286 -0
  212. pysisyphus/intcoords/Primitive.py +137 -0
  213. pysisyphus/intcoords/RedundantCoords.py +659 -0
  214. pysisyphus/intcoords/RobustTorsion.py +59 -0
  215. pysisyphus/intcoords/Rotation.py +147 -0
  216. pysisyphus/intcoords/Stretch.py +31 -0
  217. pysisyphus/intcoords/Torsion.py +101 -0
  218. pysisyphus/intcoords/Torsion2.py +25 -0
  219. pysisyphus/intcoords/Translation.py +45 -0
  220. pysisyphus/intcoords/__init__.py +61 -0
  221. pysisyphus/intcoords/augment_bonds.py +126 -0
  222. pysisyphus/intcoords/derivatives.py +10512 -0
  223. pysisyphus/intcoords/eval.py +80 -0
  224. pysisyphus/intcoords/exceptions.py +37 -0
  225. pysisyphus/intcoords/findiffs.py +48 -0
  226. pysisyphus/intcoords/generate_derivatives.py +414 -0
  227. pysisyphus/intcoords/helpers.py +235 -0
  228. pysisyphus/intcoords/logging_conf.py +10 -0
  229. pysisyphus/intcoords/mp_derivatives.py +10836 -0
  230. pysisyphus/intcoords/setup.py +962 -0
  231. pysisyphus/intcoords/setup_fast.py +176 -0
  232. pysisyphus/intcoords/update.py +272 -0
  233. pysisyphus/intcoords/valid.py +89 -0
  234. pysisyphus/interpolate/Geodesic.py +93 -0
  235. pysisyphus/interpolate/IDPP.py +55 -0
  236. pysisyphus/interpolate/Interpolator.py +116 -0
  237. pysisyphus/interpolate/LST.py +70 -0
  238. pysisyphus/interpolate/Redund.py +152 -0
  239. pysisyphus/interpolate/__init__.py +9 -0
  240. pysisyphus/interpolate/helpers.py +34 -0
  241. pysisyphus/io/__init__.py +22 -0
  242. pysisyphus/io/aomix.py +178 -0
  243. pysisyphus/io/cjson.py +24 -0
  244. pysisyphus/io/crd.py +101 -0
  245. pysisyphus/io/cube.py +220 -0
  246. pysisyphus/io/fchk.py +184 -0
  247. pysisyphus/io/hdf5.py +49 -0
  248. pysisyphus/io/hessian.py +72 -0
  249. pysisyphus/io/mol2.py +146 -0
  250. pysisyphus/io/molden.py +293 -0
  251. pysisyphus/io/orca.py +189 -0
  252. pysisyphus/io/pdb.py +269 -0
  253. pysisyphus/io/psf.py +79 -0
  254. pysisyphus/io/pubchem.py +31 -0
  255. pysisyphus/io/qcschema.py +34 -0
  256. pysisyphus/io/sdf.py +29 -0
  257. pysisyphus/io/xyz.py +61 -0
  258. pysisyphus/io/zmat.py +175 -0
  259. pysisyphus/irc/DWI.py +108 -0
  260. pysisyphus/irc/DampedVelocityVerlet.py +134 -0
  261. pysisyphus/irc/Euler.py +22 -0
  262. pysisyphus/irc/EulerPC.py +345 -0
  263. pysisyphus/irc/GonzalezSchlegel.py +187 -0
  264. pysisyphus/irc/IMKMod.py +164 -0
  265. pysisyphus/irc/IRC.py +878 -0
  266. pysisyphus/irc/IRCDummy.py +10 -0
  267. pysisyphus/irc/Instanton.py +307 -0
  268. pysisyphus/irc/LQA.py +53 -0
  269. pysisyphus/irc/ModeKill.py +136 -0
  270. pysisyphus/irc/ParamPlot.py +53 -0
  271. pysisyphus/irc/RK4.py +36 -0
  272. pysisyphus/irc/__init__.py +31 -0
  273. pysisyphus/irc/initial_displ.py +219 -0
  274. pysisyphus/linalg.py +411 -0
  275. pysisyphus/line_searches/Backtracking.py +88 -0
  276. pysisyphus/line_searches/HagerZhang.py +184 -0
  277. pysisyphus/line_searches/LineSearch.py +232 -0
  278. pysisyphus/line_searches/StrongWolfe.py +108 -0
  279. pysisyphus/line_searches/__init__.py +9 -0
  280. pysisyphus/line_searches/interpol.py +15 -0
  281. pysisyphus/modefollow/NormalMode.py +40 -0
  282. pysisyphus/modefollow/__init__.py +10 -0
  283. pysisyphus/modefollow/davidson.py +199 -0
  284. pysisyphus/modefollow/lanczos.py +95 -0
  285. pysisyphus/optimizers/BFGS.py +99 -0
  286. pysisyphus/optimizers/BacktrackingOptimizer.py +113 -0
  287. pysisyphus/optimizers/ConjugateGradient.py +98 -0
  288. pysisyphus/optimizers/CubicNewton.py +75 -0
  289. pysisyphus/optimizers/FIRE.py +113 -0
  290. pysisyphus/optimizers/HessianOptimizer.py +1176 -0
  291. pysisyphus/optimizers/LBFGS.py +228 -0
  292. pysisyphus/optimizers/LayerOpt.py +411 -0
  293. pysisyphus/optimizers/MicroOptimizer.py +169 -0
  294. pysisyphus/optimizers/NCOptimizer.py +90 -0
  295. pysisyphus/optimizers/Optimizer.py +1084 -0
  296. pysisyphus/optimizers/PreconLBFGS.py +260 -0
  297. pysisyphus/optimizers/PreconSteepestDescent.py +7 -0
  298. pysisyphus/optimizers/QuickMin.py +74 -0
  299. pysisyphus/optimizers/RFOptimizer.py +181 -0
  300. pysisyphus/optimizers/RSA.py +99 -0
  301. pysisyphus/optimizers/StabilizedQNMethod.py +248 -0
  302. pysisyphus/optimizers/SteepestDescent.py +23 -0
  303. pysisyphus/optimizers/StringOptimizer.py +173 -0
  304. pysisyphus/optimizers/__init__.py +41 -0
  305. pysisyphus/optimizers/closures.py +301 -0
  306. pysisyphus/optimizers/cls_map.py +58 -0
  307. pysisyphus/optimizers/exceptions.py +6 -0
  308. pysisyphus/optimizers/gdiis.py +280 -0
  309. pysisyphus/optimizers/guess_hessians.py +311 -0
  310. pysisyphus/optimizers/hessian_updates.py +355 -0
  311. pysisyphus/optimizers/poly_fit.py +285 -0
  312. pysisyphus/optimizers/precon.py +153 -0
  313. pysisyphus/optimizers/restrict_step.py +24 -0
  314. pysisyphus/pack.py +172 -0
  315. pysisyphus/peakdetect.py +948 -0
  316. pysisyphus/plot.py +1031 -0
  317. pysisyphus/run.py +2106 -0
  318. pysisyphus/socket_helper.py +74 -0
  319. pysisyphus/stocastic/FragmentKick.py +132 -0
  320. pysisyphus/stocastic/Kick.py +81 -0
  321. pysisyphus/stocastic/Pipeline.py +303 -0
  322. pysisyphus/stocastic/__init__.py +21 -0
  323. pysisyphus/stocastic/align.py +127 -0
  324. pysisyphus/testing.py +96 -0
  325. pysisyphus/thermo.py +156 -0
  326. pysisyphus/trj.py +824 -0
  327. pysisyphus/tsoptimizers/RSIRFOptimizer.py +56 -0
  328. pysisyphus/tsoptimizers/RSPRFOptimizer.py +182 -0
  329. pysisyphus/tsoptimizers/TRIM.py +59 -0
  330. pysisyphus/tsoptimizers/TSHessianOptimizer.py +463 -0
  331. pysisyphus/tsoptimizers/__init__.py +23 -0
  332. pysisyphus/wavefunction/Basis.py +239 -0
  333. pysisyphus/wavefunction/DIIS.py +76 -0
  334. pysisyphus/wavefunction/__init__.py +25 -0
  335. pysisyphus/wavefunction/build_ext.py +42 -0
  336. pysisyphus/wavefunction/cart2sph.py +190 -0
  337. pysisyphus/wavefunction/diabatization.py +304 -0
  338. pysisyphus/wavefunction/excited_states.py +435 -0
  339. pysisyphus/wavefunction/gen_ints.py +1811 -0
  340. pysisyphus/wavefunction/helpers.py +104 -0
  341. pysisyphus/wavefunction/ints/__init__.py +0 -0
  342. pysisyphus/wavefunction/ints/boys.py +193 -0
  343. pysisyphus/wavefunction/ints/boys_table_N_64_xasym_27.1_step_0.01.npy +0 -0
  344. pysisyphus/wavefunction/ints/cart_gto3d.py +176 -0
  345. pysisyphus/wavefunction/ints/coulomb3d.py +25928 -0
  346. pysisyphus/wavefunction/ints/diag_quadrupole3d.py +10036 -0
  347. pysisyphus/wavefunction/ints/dipole3d.py +8762 -0
  348. pysisyphus/wavefunction/ints/int2c2e3d.py +7198 -0
  349. pysisyphus/wavefunction/ints/int3c2e3d_sph.py +65040 -0
  350. pysisyphus/wavefunction/ints/kinetic3d.py +8240 -0
  351. pysisyphus/wavefunction/ints/ovlp3d.py +3777 -0
  352. pysisyphus/wavefunction/ints/quadrupole3d.py +15054 -0
  353. pysisyphus/wavefunction/ints/self_ovlp3d.py +198 -0
  354. pysisyphus/wavefunction/localization.py +458 -0
  355. pysisyphus/wavefunction/multipole.py +159 -0
  356. pysisyphus/wavefunction/normalization.py +36 -0
  357. pysisyphus/wavefunction/pop_analysis.py +134 -0
  358. pysisyphus/wavefunction/shells.py +1171 -0
  359. pysisyphus/wavefunction/wavefunction.py +504 -0
  360. pysisyphus/wrapper/__init__.py +11 -0
  361. pysisyphus/wrapper/exceptions.py +2 -0
  362. pysisyphus/wrapper/jmol.py +120 -0
  363. pysisyphus/wrapper/mwfn.py +169 -0
  364. pysisyphus/wrapper/packmol.py +71 -0
  365. pysisyphus/xyzloader.py +168 -0
  366. pysisyphus/yaml_mods.py +45 -0
  367. thermoanalysis/LICENSE +674 -0
  368. thermoanalysis/QCData.py +244 -0
  369. thermoanalysis/__init__.py +0 -0
  370. thermoanalysis/config.py +3 -0
  371. thermoanalysis/constants.py +20 -0
  372. thermoanalysis/thermo.py +1011 -0
@@ -0,0 +1,72 @@
1
+ import numpy as np
2
+
3
+ from pysisyphus.intcoords.Torsion import Torsion
4
+
5
+
6
+ class DummyTorsion(Torsion):
7
+ def __init__(self, indices, *args, fix_inner=True, **kwargs):
8
+ self.fix_inner = fix_inner
9
+ kwargs["calc_kwargs"] = ("fix_inner",)
10
+ super().__init__(indices, *args, **kwargs)
11
+ self.log("DummyTorsion is never checked for collinear atoms!")
12
+
13
+ @staticmethod
14
+ def get_fourth_coords(coords3d, indices, r=1.889, theta=90):
15
+ r"""
16
+ M N <- add
17
+ \ /
18
+ u v
19
+ \ /
20
+ P
21
+ m, o, p, n = indices
22
+ """
23
+ _, O_, P_ = indices
24
+ # Center
25
+ P = coords3d[P_]
26
+ # Bond, pointing away from O to M
27
+ u = coords3d[O_] - P
28
+ # Direction of u along x axis (left/right)
29
+ sign = np.sign(u[0])
30
+ # Polar coordinates
31
+ x = r * np.cos(theta)
32
+ y = r * np.sin(theta)
33
+ # Translate from center with correct orientation
34
+ fourth_coords = P + (sign * x, sign * y, 0.0)
35
+ return fourth_coords
36
+
37
+ @staticmethod
38
+ def get_coords3d_and_indices_ext(coords3d, indices):
39
+ fourth_coords = DummyTorsion.get_fourth_coords(coords3d, indices)
40
+ fourth_ind = len(coords3d)
41
+ coords3d_ext = np.zeros((len(coords3d) + 1, 3))
42
+ coords3d_ext[:fourth_ind] = coords3d
43
+ coords3d_ext[fourth_ind] = fourth_coords
44
+ indices_ext = indices + [fourth_ind]
45
+ return coords3d_ext, indices_ext
46
+
47
+ @staticmethod
48
+ def _weight(*args, **kwargs):
49
+ return 1
50
+
51
+ @staticmethod
52
+ def _calculate(coords3d, indices, gradient=False, fix_inner=False):
53
+ coords3d_ext, indices_ext = DummyTorsion.get_coords3d_and_indices_ext(
54
+ coords3d, indices
55
+ )
56
+
57
+ results = Torsion._calculate(coords3d_ext, indices_ext, gradient=gradient)
58
+ if gradient:
59
+ val, grad = results
60
+
61
+ # Remove entries that belong to the dummy atom.
62
+ grad = grad[:-3]
63
+
64
+ # Zero out contributions of the inner two atoms in the torsion.
65
+ # So basically only the atom at the first index moves.
66
+ #
67
+ # This usually degrades optimization convergence.
68
+ if fix_inner:
69
+ grad.reshape(-1, 3)[indices_ext[1:3]] = 0.0
70
+ return val, grad.flatten()
71
+ else:
72
+ return results
@@ -0,0 +1,105 @@
1
+ from math import sin
2
+
3
+ import numpy as np
4
+
5
+ from pysisyphus.intcoords.derivatives import dq_lb, d2q_lb
6
+ from pysisyphus.intcoords.Primitive import Primitive
7
+ from pysisyphus.linalg import cross3, norm3
8
+
9
+
10
+ # [1] 10.1080/00268977200102361
11
+ # Hoy, 1972
12
+ # [2] 10.1063/1.474377
13
+ # Chuang, 1997
14
+ # [3] 10.1063/1.468630
15
+ # Jackels, 1995
16
+ # Refs. [2] and [3] give a short discussion of the linear bends.
17
+
18
+
19
+ class LinearBend(Primitive):
20
+ def __init__(self, *args, complement=False, **kwargs):
21
+ kwargs["calc_kwargs"] = ("complement", "cross_vec")
22
+ super().__init__(*args, **kwargs)
23
+
24
+ self.complement = complement
25
+ self.cross_vec = None
26
+
27
+ @staticmethod
28
+ def _weight(atoms, coords3d, indices, f_damping):
29
+ m, o, n = indices
30
+ rho_mo = LinearBend.rho(atoms, coords3d, (m, o))
31
+ rho_on = LinearBend.rho(atoms, coords3d, (o, n))
32
+
33
+ # Repeated code to avoid import of intcoords.Bend
34
+ u_dash = coords3d[m] - coords3d[o]
35
+ v_dash = coords3d[n] - coords3d[o]
36
+ u_norm = norm3(u_dash)
37
+ v_norm = norm3(v_dash)
38
+ u = u_dash / u_norm
39
+ v = v_dash / v_norm
40
+ rad = np.arccos(u.dot(v))
41
+
42
+ return (rho_mo * rho_on) ** 0.5 * (f_damping + (1 - f_damping) * sin(rad))
43
+
44
+ @staticmethod
45
+ def _get_orthogonal_direction(coords3d, indices, complement=False, cross_vec=None):
46
+ m, o, n = indices
47
+ u_dash = coords3d[m] - coords3d[o]
48
+ u_norm = norm3(u_dash)
49
+ u = u_dash / u_norm
50
+
51
+ if cross_vec is None:
52
+ cross_vec = LinearBend._get_cross_vec(coords3d, indices)
53
+ # Generate first orthogonal direction
54
+ w_dash = cross3(u, cross_vec)
55
+ w = w_dash / norm3(w_dash)
56
+
57
+ # Generate second orthogonal direction
58
+ if complement:
59
+ w = cross3(u, w)
60
+ return w
61
+
62
+ def calculate(self, coords3d, indices=None, gradient=False):
63
+ if self.cross_vec is None:
64
+ self.set_cross_vec(coords3d, indices)
65
+
66
+ return super().calculate(coords3d, indices, gradient)
67
+
68
+ @staticmethod
69
+ def _calculate(coords3d, indices, gradient=False, complement=False, cross_vec=None):
70
+ m, o, n = indices
71
+ u_dash = coords3d[m] - coords3d[o]
72
+ v_dash = coords3d[n] - coords3d[o]
73
+ u_norm = norm3(u_dash)
74
+ v_norm = norm3(v_dash)
75
+ w = LinearBend._get_orthogonal_direction(
76
+ coords3d, indices, complement, cross_vec
77
+ )
78
+
79
+ lb_rad = w.dot(cross3(u_dash, v_dash)) / (u_norm * v_norm)
80
+
81
+ if gradient:
82
+ # Fourth argument is the orthogonal direction
83
+ row = np.zeros_like(coords3d)
84
+ row[indices] = dq_lb(*coords3d[indices].flatten(), *w).reshape(-1, 3)
85
+ return lb_rad, row.flatten()
86
+ return lb_rad
87
+
88
+ def jacobian(self, coords3d, indices=None):
89
+ if self.cross_vec is None:
90
+ self.set_cross_vec(coords3d, indices)
91
+
92
+ return super().jacobian(coords3d, indices)
93
+
94
+ @staticmethod
95
+ def _jacobian(coords3d, indices, complement=False, cross_vec=None):
96
+ if cross_vec is None:
97
+ cross_vec = LinearBend._get_cross_vec(coords3d, indices)
98
+
99
+ w = LinearBend._get_orthogonal_direction(
100
+ coords3d, indices, complement, cross_vec
101
+ )
102
+ return d2q_lb(*coords3d[indices].flatten(), *w)
103
+
104
+ def __str__(self):
105
+ return f"LinearBend({tuple(self.indices)}, complement={self.complement})"
@@ -0,0 +1,80 @@
1
+ import numpy as np
2
+
3
+ from pysisyphus.intcoords.Primitive import Primitive
4
+ from pysisyphus.intcoords.derivatives import dq_ld, d2q_ld
5
+ from pysisyphus.linalg import cross3, norm3
6
+
7
+
8
+ class LinearDisplacement(Primitive):
9
+ def __init__(self, *args, complement=False, **kwargs):
10
+ kwargs["calc_kwargs"] = ("complement", "cross_vec")
11
+ super().__init__(*args, **kwargs)
12
+
13
+ self.complement = complement
14
+ self.cross_vec = None
15
+
16
+ @staticmethod
17
+ def _weight(atoms, coords3d, indices, f_damping):
18
+ raise Exception("Not yet implemented!")
19
+
20
+ def calculate(self, coords3d, indices=None, gradient=False):
21
+ if self.cross_vec is None:
22
+ self.set_cross_vec(coords3d, indices)
23
+
24
+ return super().calculate(coords3d, indices, gradient)
25
+
26
+ @staticmethod
27
+ def _calculate(coords3d, indices, gradient=False, complement=False, cross_vec=None):
28
+ m, o, n = indices
29
+ w_dash = coords3d[n] - coords3d[m]
30
+ w = w_dash / norm3(w_dash)
31
+
32
+ u_dash = coords3d[m] - coords3d[o]
33
+ v_dash = coords3d[n] - coords3d[o]
34
+ u = u_dash / norm3(u_dash)
35
+ v = v_dash / norm3(v_dash)
36
+
37
+ # Vector for cross product to determine first orthogonal direction
38
+ if cross_vec is None:
39
+ cross_vec = LinearDisplacement._get_cross_vec(coords3d, indices)
40
+
41
+ if complement:
42
+ cross_vec = cross3(w, cross_vec)
43
+ cross_vec /= norm3(cross_vec)
44
+
45
+ # Orthogonal direction
46
+ y = cross3(w, cross_vec)
47
+ y /= norm3(y)
48
+
49
+ lin_disp = y.dot(u) + y.dot(v)
50
+
51
+ if gradient:
52
+ row = np.zeros_like(coords3d)
53
+ row[indices] = dq_ld(*coords3d[indices].flatten(), *cross_vec).reshape(-1, 3)
54
+ return lin_disp, row.flatten()
55
+
56
+ return lin_disp
57
+
58
+ def jacobian(self, coords3d, indices=None):
59
+ if self.cross_vec is None:
60
+ self.set_cross_vec(coords3d, indices)
61
+
62
+ return super().jacobian(coords3d, indices)
63
+
64
+ @staticmethod
65
+ def _jacobian(coords3d, indices, complement=False, cross_vec=None):
66
+ if cross_vec is None:
67
+ cross_vec = LinearDisplacement._get_cross_vec(coords3d, indices)
68
+
69
+ if complement:
70
+ m, _, n = indices
71
+ w_dash = coords3d[n] - coords3d[m]
72
+ w = w_dash / norm3(w_dash)
73
+ cross_vec = cross3(w, cross_vec)
74
+
75
+ return d2q_ld(*coords3d[indices].flatten(), *cross_vec)
76
+
77
+ def __str__(self):
78
+ return (
79
+ f"LinearDisplacement({tuple(self.indices)}, complement={self.complement})"
80
+ )
@@ -0,0 +1,59 @@
1
+ import numpy as np
2
+
3
+ from pysisyphus.intcoords.Primitive import Primitive
4
+ from pysisyphus.intcoords.derivatives import dq_oop, d2q_oop
5
+ from pysisyphus.linalg import cross3, norm3
6
+
7
+
8
+ class OutOfPlane(Primitive):
9
+ """
10
+ [1] https://doi.org/10.1002/(SICI)1096-987X(19990730)20:10<1067::AID-JCC9>3.0.CO;2-V
11
+ Lee, 1999
12
+ """
13
+
14
+ @staticmethod
15
+ def _weight(atoms, coords3d, indices, f_damping):
16
+ raise Exception("Not yet implemented!")
17
+
18
+ @staticmethod
19
+ def _calculate(coords3d, indices, gradient=False):
20
+ """
21
+ P
22
+ / | \
23
+ / | \
24
+ u' v' w'
25
+ / | \
26
+ m n o
27
+ """
28
+ # p is apex
29
+ m, n, o, p = indices
30
+
31
+ u_dash = coords3d[m] - coords3d[p]
32
+ v_dash = coords3d[n] - coords3d[p]
33
+ w_dash = coords3d[o] - coords3d[p]
34
+
35
+ u = u_dash / norm3(u_dash)
36
+ v = v_dash / norm3(v_dash)
37
+ w = w_dash / norm3(w_dash)
38
+
39
+ z_dash = cross3(u, v) + cross3(v, w) + cross3(w, u)
40
+ z = z_dash / norm3(z_dash)
41
+
42
+ oop_coord = z.dot(u)
43
+
44
+ if gradient:
45
+ grad = dq_oop(*coords3d[m], *coords3d[n], *coords3d[o], *coords3d[p])
46
+ grad = grad.reshape(4, 3)
47
+ row = np.zeros_like(coords3d)
48
+ row[m, :] = grad[0]
49
+ row[n, :] = grad[1]
50
+ row[o, :] = grad[2]
51
+ row[p, :] = grad[3]
52
+ row = row.flatten()
53
+ return oop_coord, row
54
+
55
+ return oop_coord
56
+
57
+ @staticmethod
58
+ def _jacobian(coords3d, indices):
59
+ return d2q_oop(*coords3d[indices].flatten())
@@ -0,0 +1,286 @@
1
+ import itertools as it
2
+ from typing import Union, Sequence
3
+
4
+ import numpy as np
5
+
6
+ from pysisyphus.constants import BOHR2ANG
7
+ from pysisyphus.helpers_pure import OrderedEnum
8
+ from pysisyphus.intcoords import (
9
+ Bend,
10
+ Bend2,
11
+ BondedFragment,
12
+ DummyImproper,
13
+ DummyTorsion,
14
+ DistanceFunction,
15
+ CartesianX,
16
+ CartesianY,
17
+ CartesianZ,
18
+ LinearBend,
19
+ LinearDisplacement,
20
+ OutOfPlane,
21
+ RobustTorsion1,
22
+ RobustTorsion2,
23
+ RotationA,
24
+ RotationB,
25
+ RotationC,
26
+ Stretch,
27
+ TranslationX,
28
+ TranslationY,
29
+ TranslationZ,
30
+ Torsion,
31
+ Torsion2,
32
+ )
33
+
34
+
35
+ class PrimTypes(OrderedEnum):
36
+ BOND = 0
37
+ AUX_BOND = 1
38
+ HYDROGEN_BOND = 2
39
+ INTERFRAG_BOND = 3
40
+ AUX_INTERFRAG_BOND = 4
41
+ BEND = 5
42
+ LINEAR_BEND = 6
43
+ LINEAR_BEND_COMPLEMENT = 7
44
+ PROPER_DIHEDRAL = 8
45
+ IMPROPER_DIHEDRAL = 9
46
+ OUT_OF_PLANE = 10
47
+ LINEAR_DISPLACEMENT = 11
48
+ LINEAR_DISPLACEMENT_COMPLEMENT = 12
49
+ TRANSLATION = 13
50
+ TRANSLATION_X = 14
51
+ TRANSLATION_Y = 15
52
+ TRANSLATION_Z = 16
53
+ ROTATION = 17
54
+ ROTATION_A = 18
55
+ ROTATION_B = 19
56
+ ROTATION_C = 20
57
+ CARTESIAN = 21
58
+ CARTESIAN_X = 22
59
+ CARTESIAN_Y = 23
60
+ CARTESIAN_Z = 24
61
+ BONDED_FRAGMENT = 25
62
+ DUMMY_TORSION = 26
63
+ DISTANCE_FUNCTION = 27
64
+ # atan2 based bend and torsion
65
+ BEND2 = 28
66
+ PROPER_DIHEDRAL2 = 29
67
+ DUMMY_IMPROPER = 30
68
+ ROBUST_TORSION1 = 31
69
+ ROBUST_TORSION2 = 32
70
+
71
+
72
+ PrimTypeLike = Union[PrimTypes, str]
73
+
74
+
75
+ # Alias for easier access
76
+ PT = PrimTypes
77
+
78
+
79
+ PrimTypeShortcuts = {
80
+ "X": [PT.CARTESIAN_X],
81
+ "Y": [PT.CARTESIAN_Y],
82
+ "Z": [PT.CARTESIAN_Z],
83
+ "XY": [PT.CARTESIAN_X, PT.CARTESIAN_Y],
84
+ "XZ": [PT.CARTESIAN_X, PT.CARTESIAN_Z],
85
+ "YZ": [PT.CARTESIAN_Y, PT.CARTESIAN_Z],
86
+ "XYZ": [PT.CARTESIAN_X, PT.CARTESIAN_Y, PT.CARTESIAN_Z],
87
+ "ATOM": [PT.CARTESIAN_X, PT.CARTESIAN_Y, PT.CARTESIAN_Z],
88
+ # Primitive aliases
89
+ "B": [PT.BOND],
90
+ "A": [PT.BEND],
91
+ "A2": [PT.BEND2],
92
+ "D": [PT.PROPER_DIHEDRAL],
93
+ "D2": [PT.PROPER_DIHEDRAL2],
94
+ "DIHEDRAL": [PT.PROPER_DIHEDRAL],
95
+ "DIHEDRAL2": [PT.PROPER_DIHEDRAL2],
96
+ "TORSION": [PT.PROPER_DIHEDRAL],
97
+ "TORSION2": [PT.PROPER_DIHEDRAL2],
98
+ "RTORSION1": [PT.ROBUST_TORSION1],
99
+ "RTORSION2": [PT.ROBUST_TORSION2],
100
+ # Translation & Rotation coordinates
101
+ "TRANSLATION": [PT.TRANSLATION_X, PT.TRANSLATION_Y, PT.TRANSLATION_Z],
102
+ "ROTATION": [PT.ROTATION_A, PT.ROTATION_B, PT.ROTATION_C],
103
+ "DIST_FUNC": [PT.DISTANCE_FUNCTION],
104
+ }
105
+
106
+ # The tuples below can be used to decide whether a given type belongs
107
+ # to a certain class of primitive.
108
+ Bonds = (
109
+ PT.BOND,
110
+ PT.AUX_BOND,
111
+ PT.HYDROGEN_BOND,
112
+ PT.INTERFRAG_BOND,
113
+ PT.AUX_INTERFRAG_BOND,
114
+ PT.DISTANCE_FUNCTION,
115
+ )
116
+ Bends = (PT.BEND, PT.BEND2)
117
+ LinearBends = (
118
+ PT.LINEAR_BEND,
119
+ PT.LINEAR_BEND_COMPLEMENT,
120
+ PT.LINEAR_DISPLACEMENT,
121
+ PT.LINEAR_DISPLACEMENT_COMPLEMENT,
122
+ )
123
+ Dihedrals = (
124
+ PT.PROPER_DIHEDRAL,
125
+ PT.IMPROPER_DIHEDRAL,
126
+ PT.PROPER_DIHEDRAL2,
127
+ PT.DUMMY_IMPROPER,
128
+ PT.ROBUST_TORSION1,
129
+ PT.ROBUST_TORSION2,
130
+ )
131
+ OutOfPlanes = (PT.OUT_OF_PLANE,)
132
+ Cartesians = (PT.CARTESIAN_X, PT.CARTESIAN_Y, PT.CARTESIAN_Z)
133
+ Rotations = (PT.ROTATION_A, PT.ROTATION_B, PT.ROTATION_C)
134
+ Translations = (
135
+ PT.TRANSLATION_X,
136
+ PT.TRANSLATION_Y,
137
+ PT.TRANSLATION_Z,
138
+ PT.BONDED_FRAGMENT,
139
+ )
140
+ DummyCoords = (PT.DUMMY_TORSION,)
141
+
142
+
143
+ def get_rot_coord(cls):
144
+ def func(indices, ref_coords3d):
145
+ return cls(indices, ref_coords3d=ref_coords3d)
146
+
147
+ return func
148
+
149
+
150
+ def get_bonded_frag_coord():
151
+ def func(indices):
152
+ indices_ = indices[:-2]
153
+ bond_indices = indices[-2:]
154
+ return BondedFragment(indices_, bond_indices=bond_indices)
155
+
156
+ return func
157
+
158
+
159
+ def get_dist_func():
160
+ def func(indices):
161
+ indices_ = indices[:4]
162
+ coeff = indices[4]
163
+ return DistanceFunction(indices_, coeff=coeff)
164
+
165
+ return func
166
+
167
+
168
+ # Maps primitive types to their classes
169
+ PrimMap = {
170
+ PT.BOND: Stretch,
171
+ PT.AUX_BOND: Stretch,
172
+ PT.HYDROGEN_BOND: Stretch,
173
+ PT.INTERFRAG_BOND: Stretch,
174
+ PT.AUX_INTERFRAG_BOND: Stretch,
175
+ PT.BEND: Bend,
176
+ PT.BEND2: Bend2,
177
+ PT.LINEAR_BEND: LinearBend,
178
+ PT.LINEAR_BEND_COMPLEMENT: lambda indices: LinearBend(indices, complement=True),
179
+ PT.PROPER_DIHEDRAL: lambda indices: Torsion(indices, periodic=True),
180
+ PT.PROPER_DIHEDRAL2: lambda indices: Torsion2(indices, periodic=True),
181
+ PT.IMPROPER_DIHEDRAL: lambda indices: Torsion(indices, periodic=True),
182
+ PT.ROBUST_TORSION1: lambda indices: RobustTorsion1(indices),
183
+ PT.ROBUST_TORSION2: lambda indices: RobustTorsion2(indices),
184
+ PT.OUT_OF_PLANE: OutOfPlane,
185
+ PT.LINEAR_DISPLACEMENT: LinearDisplacement,
186
+ PT.LINEAR_DISPLACEMENT_COMPLEMENT: lambda indices: LinearDisplacement(
187
+ indices, complement=True
188
+ ),
189
+ PT.TRANSLATION_X: TranslationX,
190
+ PT.TRANSLATION_Y: TranslationY,
191
+ PT.TRANSLATION_Z: TranslationZ,
192
+ PT.ROTATION_A: get_rot_coord(RotationA),
193
+ PT.ROTATION_B: get_rot_coord(RotationB),
194
+ PT.ROTATION_C: get_rot_coord(RotationC),
195
+ PT.CARTESIAN_X: CartesianX,
196
+ PT.CARTESIAN_Y: CartesianY,
197
+ PT.CARTESIAN_Z: CartesianZ,
198
+ PT.BONDED_FRAGMENT: get_bonded_frag_coord(),
199
+ PT.DUMMY_TORSION: lambda indices: DummyTorsion(
200
+ indices,
201
+ periodic=True,
202
+ ),
203
+ PT.DISTANCE_FUNCTION: get_dist_func(),
204
+ PT.DUMMY_IMPROPER: lambda indices: DummyImproper(
205
+ indices,
206
+ periodic=True,
207
+ ),
208
+ }
209
+
210
+
211
+ def normalize_prim_input(prim_inp):
212
+ """Normalize input for define_prims and constrain_prims
213
+
214
+ The intcoords.RedundantCoords constructor expects lists of integer lists
215
+ (tuples) for arguments like 'define_prims' and 'constrain_prims'. The first item
216
+ of every list determines the type of primitive coordinate. Currently
217
+ there are about 20 different types and it is hard to remember all of
218
+ them.
219
+
220
+ So we also allow a more human friendly input, that is normalized here.
221
+ The most common primitives are:
222
+
223
+ 0: BOND
224
+ 5: BEND
225
+ 8: PROPER_DIHEDRAL
226
+
227
+ This function maps inputs like ["BOND", 1, 2] to [PrimTypes.BOND, 1, 2] etc.
228
+
229
+ Always returns a list of tuples, as some prim_inps expand to multiple
230
+ coordinates, e.g., XYZ or ATOM.
231
+ """
232
+ if prim_inp is None:
233
+ return []
234
+
235
+ prim_type, *indices = prim_inp
236
+ indices = list(map(int, indices))
237
+
238
+ # Nothing to do
239
+ if isinstance(prim_type, PrimTypes):
240
+ return [prim_inp]
241
+
242
+ # First check if we got something like an integer
243
+ try:
244
+ return [tuple([PrimTypes(int(prim_type))] + indices)]
245
+ # Raised when prim_type is, e.g., "BOND"
246
+ except ValueError:
247
+ pass
248
+
249
+ # Check if we got a PrimType name
250
+ try:
251
+ prim_type_ = getattr(PrimTypes, str(prim_type).upper())
252
+ return [tuple([prim_type_] + indices)]
253
+ except AttributeError:
254
+ pass
255
+
256
+ # Check if we got a shortcut, e.g, X/Y/Z/XYZ/ATOM etc.
257
+ try:
258
+ prim_types_ = PrimTypeShortcuts[str(prim_type).upper()]
259
+ return [tuple([prim_type_] + indices) for prim_type_ in prim_types_]
260
+ except KeyError as error:
261
+ print(f"Could not normalize 'prim_inp'={prim_inp}!")
262
+ raise error
263
+
264
+
265
+ def normalize_prim_inputs(prim_inps):
266
+ # Flatten list of tuples
267
+ return list(it.chain(*[normalize_prim_input(pi) for pi in prim_inps]))
268
+
269
+
270
+ def prims_from_prim_inputs(prim_inps):
271
+ norm_prim_inps = normalize_prim_inputs(prim_inps)
272
+ prims = [PrimMap[prim_type](indices) for prim_type, *indices in norm_prim_inps]
273
+ return prims
274
+
275
+
276
+ def prim_for_human(prim_type: PrimTypes, val: Sequence[int]):
277
+ if prim_type in Bonds:
278
+ val_conv = val * BOHR2ANG
279
+ unit = " Å"
280
+ elif prim_type in Bends:
281
+ unit = "°"
282
+ val_conv = np.rad2deg(val)
283
+ else:
284
+ val_conv = val
285
+ unit = ""
286
+ return val_conv, unit