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,20 @@
1
+ from pysisyphus.calculators.AnaPotBase import AnaPotBase
2
+
3
+
4
+ class AnaPot4(AnaPotBase):
5
+
6
+ def __init__(self):
7
+ V_str = "-10*x**2 + 10*y**2 + 4*sin(x*y)-2*x+x**4"
8
+ xlim = (-3.5, 3.5)
9
+ ylim = (-3.5, 3.5)
10
+ super().__init__(V_str=V_str, xlim=xlim, ylim=ylim)
11
+
12
+ def __str__(self):
13
+ return "AnaPot4 calculator"
14
+
15
+
16
+ if __name__ == "__main__":
17
+ ap4 = AnaPot4()
18
+ ap4.plot()
19
+ import matplotlib.pyplot as plt
20
+ plt.show()
@@ -0,0 +1,337 @@
1
+ from matplotlib import cm
2
+ import matplotlib.animation as animation
3
+ import matplotlib.pyplot as plt
4
+ from mpl_toolkits.mplot3d import Axes3D
5
+ import numpy as np
6
+ from sympy import symbols, diff, lambdify, sympify
7
+
8
+ from pysisyphus.calculators.Calculator import Calculator
9
+ from pysisyphus.Geometry import Geometry
10
+ from pysisyphus.interpolate import interpolate
11
+ from pysisyphus.plotters.AnimPlot import AnimPlot
12
+
13
+
14
+ class AnaPotBase(Calculator):
15
+ def __init__(
16
+ self,
17
+ V_str,
18
+ scale=1.0,
19
+ xlim=(-1, 1),
20
+ ylim=(-1, 1),
21
+ levels=None,
22
+ use_sympify=True,
23
+ minima=None,
24
+ saddles=None,
25
+ ):
26
+ super().__init__()
27
+ self.V_str = V_str
28
+ self.scale = scale
29
+ self.xlim = xlim
30
+ self.ylim = ylim
31
+ if levels is not None:
32
+ levels = levels * self.scale
33
+ self.levels = levels
34
+ if minima is None:
35
+ minima = list()
36
+ self.minima = np.array(minima, dtype=float)
37
+ if saddles is None:
38
+ saddles = list()
39
+ self.saddles = np.array(saddles, dtype=float)
40
+
41
+ x, y = symbols("x y")
42
+ if use_sympify:
43
+ V = sympify(V_str)
44
+ else:
45
+ V = V_str
46
+ dVdx = diff(V, x)
47
+ dVdy = diff(V, y)
48
+ self.V = lambdify((x, y), V, "numpy")
49
+ self.dVdx = lambdify((x, y), dVdx, "numpy")
50
+ self.dVdy = lambdify((x, y), dVdy, "numpy")
51
+
52
+ dVdxdx = diff(V, x, x)
53
+ dVdxdy = diff(V, x, y)
54
+ dVdydy = diff(V, y, y)
55
+
56
+ self.dVdxdx = lambdify((x, y), dVdxdx, "numpy")
57
+ self.dVdxdy = lambdify((x, y), dVdxdy, "numpy")
58
+ self.dVdydy = lambdify((x, y), dVdydy, "numpy")
59
+
60
+ self.fake_atoms = ("X",) # X, dummy atom
61
+
62
+ self.analytical_2d = True
63
+ self.energy_calcs = 0
64
+ self.forces_calcs = 0
65
+ self.hessian_calcs = 0
66
+
67
+ # Dummies
68
+ self.mult = 1
69
+ self.charge = 0
70
+
71
+ self.fig = None
72
+ self.ax = None
73
+
74
+ def get_energy(self, atoms, coords):
75
+ self.energy_calcs += 1
76
+ x, y, z = coords
77
+ energy = self.scale * self.V(x, y)
78
+ return {
79
+ "energy": energy,
80
+ }
81
+
82
+ def get_forces(self, atoms, coords):
83
+ self.forces_calcs += 1
84
+ x, y, z = coords
85
+ dVdx = self.dVdx(x, y)
86
+ dVdy = self.dVdy(x, y)
87
+ dVdz = np.zeros_like(dVdx)
88
+ forces = self.scale * -np.array((dVdx, dVdy, dVdz))
89
+ results = {
90
+ "forces": forces,
91
+ }
92
+ results.update(self.get_energy(atoms, coords))
93
+ return results
94
+
95
+ def get_hessian(self, atoms, coords):
96
+ self.hessian_calcs += 1
97
+ x, y, z = coords
98
+ dVdxdx = self.dVdxdx(x, y)
99
+ dVdxdy = self.dVdxdy(x, y)
100
+ dVdydy = self.dVdydy(x, y)
101
+ hessian = self.scale * np.array(
102
+ ((dVdxdx, dVdxdy, 0), (dVdxdy, dVdydy, 0), (0, 0, 0))
103
+ )
104
+ results = {
105
+ "hessian": hessian,
106
+ }
107
+ results.update(self.get_energy(atoms, coords))
108
+ return results
109
+
110
+ def statistics(self):
111
+ return (
112
+ f"Energy calculations: {self.energy_calcs}, Force calculations: "
113
+ f"{self.forces_calcs}, Hessian calculations: {self.hessian_calcs}"
114
+ )
115
+
116
+ def plot(self, levels=None, show=False, **figkwargs):
117
+ if not self.fig or not self.ax:
118
+ self.fig, self.ax = plt.subplots(**figkwargs)
119
+
120
+ x = np.linspace(*self.xlim, 100)
121
+ y = np.linspace(*self.ylim, 100)
122
+ X, Y = np.meshgrid(x, y)
123
+ Z = np.full_like(X, 0)
124
+ pot_coords = np.stack((X, Y, Z))
125
+ pot = self.get_energy(self.fake_atoms, pot_coords)["energy"]
126
+
127
+ if levels is None:
128
+ if self.levels is None:
129
+ levels = np.linspace(pot.min(), pot.max(), 35)
130
+ else:
131
+ levels = self.levels
132
+
133
+ # Draw the contourlines of the potential
134
+ contours = self.ax.contour(X, Y, pot, levels)
135
+
136
+ # Avoid duplicated colorbars
137
+ if len(self.fig.axes) == 1:
138
+ self.fig.colorbar(contours)
139
+
140
+ if show:
141
+ plt.show()
142
+
143
+ def plot3d(
144
+ self,
145
+ levels=None,
146
+ show=False,
147
+ zlim=None,
148
+ vmin=None,
149
+ vmax=None,
150
+ resolution=100,
151
+ rcount=50,
152
+ ccount=50,
153
+ nan_above=None,
154
+ init_view=None,
155
+ colorbar=False,
156
+ **figkwargs,
157
+ ):
158
+ self.fig = plt.figure(**figkwargs)
159
+ self.ax = self.fig.add_subplot(111, projection="3d")
160
+ x = np.linspace(*self.xlim, resolution)
161
+ y = np.linspace(*self.ylim, resolution)
162
+ X, Y = np.meshgrid(x, y)
163
+ Z = np.full_like(X, 0)
164
+ pot_coords = np.stack((X, Y, Z))
165
+ pot = self.get_energy(self.fake_atoms, pot_coords)["energy"]
166
+ if nan_above:
167
+ pot[pot > nan_above] = np.nan
168
+
169
+ if vmin is None:
170
+ vmin = np.nanmin(pot)
171
+ if vmax is None:
172
+ vmax = 0.125 * np.nanmax(pot)
173
+ surf = self.ax.plot_surface(
174
+ X,
175
+ Y,
176
+ pot,
177
+ rcount=rcount,
178
+ ccount=ccount,
179
+ cmap=cm.coolwarm,
180
+ vmin=vmin,
181
+ vmax=vmax,
182
+ )
183
+ if zlim is not None:
184
+ self.ax.set_zlim(*zlim)
185
+
186
+ if colorbar:
187
+ cb = self.fig.colorbar(surf, shrink=0.45, pad=0.0)
188
+ cb.set_label("f(x,y)")
189
+
190
+ if init_view:
191
+ self.ax.view_init(*init_view)
192
+
193
+ if show:
194
+ plt.show()
195
+
196
+ return X, Y, pot
197
+
198
+ def plot_eigenvalue_structure(self, grid=50, levels=None, show=False):
199
+ self.plot(levels=levels)
200
+ xs = np.linspace(*self.xlim, grid)
201
+ ys = np.linspace(*self.ylim, grid)
202
+ X, Y = np.meshgrid(xs, ys)
203
+ z = list()
204
+ for x_, y_ in zip(X.flatten(), Y.flatten()):
205
+ H = self.get_hessian(self.fake_atoms, (x_, y_, 0))["hessian"]
206
+ w, v = np.linalg.eigh(H)
207
+ z.append(1 if (w < 0).any() else 0)
208
+ Z = np.array(z).reshape(X.shape)
209
+ self.ax.contourf(X, Y, Z, cmap=cm.Reds)
210
+ if show:
211
+ plt.show()
212
+
213
+ def plot_coords(self, xs, ys, enum=True, show=False, title=None):
214
+ self.plot()
215
+ self.ax.plot(xs, ys, "o-")
216
+ if enum:
217
+ for i, (x, y) in enumerate(zip(xs, ys)):
218
+ self.ax.annotate(i, (x, y))
219
+ if title:
220
+ self.fig.suptitle(title)
221
+ if show:
222
+ plt.show()
223
+
224
+ def plot_opt(self, opt, *args, **kwargs):
225
+ xs, ys = np.array(opt.coords).T[:2]
226
+ self.plot_coords(xs, ys, *args, **kwargs)
227
+
228
+ def plot_geoms(self, geoms, **kwargs):
229
+ coords = np.array([geom.coords for geom in geoms])
230
+ xs, ys = coords.T[:2]
231
+ self.plot_coords(xs, ys, **kwargs)
232
+
233
+ def plot_irc(self, irc, *args, **kwargs):
234
+ xs, ys = irc.all_coords.T[:2]
235
+ self.plot_coords(xs, ys, *args, **kwargs)
236
+
237
+ def anim_opt(
238
+ self, opt, energy_profile=False, colorbar=False, figsize=(8, 6), show=False
239
+ ):
240
+ try:
241
+ min_ = self.levels.min()
242
+ max_ = self.levels.max()
243
+ num = self.levels.size
244
+ levels = (min_, max_, num)
245
+ except TypeError:
246
+ levels = None
247
+
248
+ anim = AnimPlot(
249
+ self.__class__(),
250
+ opt,
251
+ xlim=self.xlim,
252
+ ylim=self.ylim,
253
+ levels=levels,
254
+ energy_profile=energy_profile,
255
+ colorbar=colorbar,
256
+ figsize=figsize,
257
+ )
258
+ anim.animate()
259
+ if show:
260
+ plt.show()
261
+ return anim
262
+
263
+ def anim_coords(self, coords, interval=50, show=False, title_func=None):
264
+ self.plot()
265
+ steps = range(len(coords))
266
+ scatter = self.ax.scatter(*coords[0][:2], s=20)
267
+
268
+ def func(frame):
269
+ if title_func:
270
+ self.ax.set_title(title_func(frame))
271
+ scatter.set_offsets(coords[frame][:2])
272
+
273
+ self.animation = animation.FuncAnimation(
274
+ self.fig, func, frames=steps, interval=interval
275
+ )
276
+
277
+ if show:
278
+ plt.show()
279
+
280
+ @classmethod
281
+ def get_geom(
282
+ cls, coords, atoms=("X",), V_str=None, calc_kwargs=None, geom_kwargs=None
283
+ ):
284
+ if calc_kwargs is None:
285
+ calc_kwargs = dict()
286
+ if geom_kwargs is None:
287
+ geom_kwargs = dict()
288
+
289
+ geom = Geometry(atoms, coords, **geom_kwargs)
290
+ if V_str:
291
+ calc_kwargs["V_str"] = V_str
292
+ geom.set_calculator(cls(**calc_kwargs))
293
+ return geom
294
+
295
+ def get_path(self, num, minima_inds=None):
296
+ between = num - 2
297
+
298
+ inds = 0, 1
299
+ if minima_inds is not None:
300
+ inds = minima_inds
301
+ initial_ind, final_ind = inds
302
+
303
+ initial_geom = self.get_geom(self.minima[initial_ind])
304
+ final_geom = self.get_geom(self.minima[final_ind])
305
+ geoms = interpolate(initial_geom, final_geom, between=between)
306
+ for geom in geoms:
307
+ # Creating new instances can be really slow when the sympy calls
308
+ # need some time. For now we just reuse the current calculator...
309
+ # geom.set_calculator(self.__class__())
310
+ geom.set_calculator(self)
311
+ return geoms
312
+
313
+ def get_geoms_from_stored_coords(
314
+ self, coords_list, i=None, calc_kwargs=None, geom_kwargs=None
315
+ ):
316
+ if calc_kwargs is None:
317
+ calc_kwargs = dict()
318
+ if geom_kwargs is None:
319
+ geom_kwargs = dict()
320
+ geoms = [
321
+ self.get_geom(coords, calc_kwargs=calc_kwargs, geom_kwargs=geom_kwargs)
322
+ for coords in coords_list
323
+ ]
324
+ if i is not None:
325
+ return geoms[i]
326
+ else:
327
+ return geoms
328
+
329
+ def get_minima(self, i=None, calc_kwargs=None, geom_kwargs=None):
330
+ return self.get_geoms_from_stored_coords(
331
+ self.minima, i=i, calc_kwargs=calc_kwargs, geom_kwargs=geom_kwargs
332
+ )
333
+
334
+ def get_saddles(self, i=None, calc_kwargs=None, geom_kwargs=None):
335
+ return self.get_geoms_from_stored_coords(
336
+ self.saddles, i=i, calc_kwargs=calc_kwargs, geom_kwargs=geom_kwargs
337
+ )
@@ -0,0 +1,25 @@
1
+ import numpy as np
2
+
3
+ from pysisyphus.calculators.AnaPotBase import AnaPotBase
4
+
5
+ # Taken from [1] 10.1021/ct9005147
6
+ # J. Chem. Theory Comput., 2010, 6 (4), pp 1136–1144
7
+
8
+ class AnaPotCBM(AnaPotBase):
9
+
10
+ def __init__(self):
11
+ V_str = "x**4 + 4*x**2*y**2 - 2*x**2 + 2*y**2"
12
+ xlim = (-1.25, 1.25)
13
+ ylim = (-0.75, 0.75)
14
+ levels = np.linspace(-1, 1.5, 80)
15
+ super().__init__(V_str=V_str, xlim=xlim, ylim=ylim, levels=levels)
16
+
17
+ def __str__(self):
18
+ return "AnaPotCBM calculator"
19
+
20
+
21
+ if __name__ == "__main__":
22
+ ap = AnaPotCBM()
23
+ ap.plot()
24
+ import matplotlib.pyplot as plt
25
+ plt.show()
@@ -0,0 +1,154 @@
1
+ # [1] https://doi.org/10.1002/jcc.26495
2
+ # Habershon, 2021
3
+
4
+ import itertools as it
5
+
6
+ import numpy as np
7
+
8
+ from pysisyphus.elem_data import COVALENT_RADII as CR
9
+
10
+
11
+ class AtomAtomTransTorque:
12
+ def __init__(
13
+ self,
14
+ geom,
15
+ frags,
16
+ A_mats,
17
+ kappa=2.0,
18
+ ):
19
+ """Atom-atom translational and torque forces.
20
+
21
+ See A.5. [1], Eq. (A6).
22
+ """
23
+ self.geom = geom
24
+ self.frags = frags
25
+ self.A_mats = A_mats
26
+ self.kappa = kappa
27
+
28
+ self.frag_num = len(self.frags)
29
+ self.pair_inds = list(it.permutations(range(self.frag_num), 2))
30
+ self.frag_sizes_sq = [len(self.frags[m]) ** 2 for m, _ in self.pair_inds]
31
+
32
+ frag_atoms = [[self.geom.atoms[a].lower() for a in frag] for frag in self.frags]
33
+ frag_cov_rads = [np.array([CR[fa.lower()] for fa in fas]) for fas in frag_atoms]
34
+ self.avg_cov_radii = list()
35
+ for m, n in self.pair_inds:
36
+ m_cov_rads = frag_cov_rads[m]
37
+ n_cov_rads = frag_cov_rads[n]
38
+ mn_avg_cov_radii = (m_cov_rads[:, None] + n_cov_rads[None, :]) / 2
39
+ self.avg_cov_radii.append(mn_avg_cov_radii)
40
+
41
+ def phi_func(A, a):
42
+ """See (A6) in [1]."""
43
+ return 1.5 if a in A else 2.0
44
+
45
+ self.phis = list()
46
+ for m, n in self.pair_inds:
47
+ key = (m, n)
48
+ A = self.A_mats[key]
49
+ self.phis.append(np.array([phi_func(A, a) for a in self.frags[m]]))
50
+
51
+ # def get_forces_naive(self, atoms, coords):
52
+ # def p(s):
53
+ # print(f"REF: {s}")
54
+
55
+ # c3d = coords.reshape(-1, 3)
56
+ # gs = [c3d[frag].mean(axis=0) for frag in self.frags]
57
+
58
+ # zt = np.zeros((self.frag_num, 3))
59
+ # zr = np.zeros((self.frag_num, 3))
60
+ # for (m, n), phis in zip(self.pair_inds, self.phis):
61
+ # p(f"m={m}, n={n}")
62
+ # mfrag = self.frags[m]
63
+ # nfrag = self.frags[n]
64
+ # A = self.A_mats[(m, n)]
65
+ # g = gs[m]
66
+ # N = 0
67
+ # for a in mfrag:
68
+ # ra = c3d[a]
69
+ # ramg = ra - g
70
+ # for b in nfrag:
71
+ # rb = c3d[b]
72
+ # rmr = rb - ra
73
+ # a_atm = atoms[a].lower()
74
+ # b_atm = atoms[b].lower()
75
+ # cab = (CR[a_atm] + CR[b_atm]) / 2
76
+ # phi = 1.5 if a in A else 2
77
+ # nrmr = np.linalg.norm(rmr)
78
+ # H = 1 if nrmr < (phi * cab) else 0
79
+ # y = cab * rmr / np.linalg.norm(rmr) - rmr
80
+ # p(f"y_(a={a},b={b})={y}")
81
+ # ny = np.linalg.norm(y)
82
+ # zt[m] += H * y.dot(ramg) * y / ny
83
+ # p(f"dot={y.dot(ramg)}")
84
+ # zr[m] += H * np.cross(y, ramg)
85
+ # p(f"zt={zt}")
86
+ # p(f"zr={zr}")
87
+ # N += H
88
+ # N *= self.frag_sizes_sq[m]
89
+ # p(f"N={N}")
90
+ # if N == 0:
91
+ # N_inv = 0
92
+ # else:
93
+ # N_inv = 1 / N
94
+ # zt[m] *= N_inv
95
+ # zr[m] *= N_inv
96
+
97
+ # forces = np.zeros_like(c3d)
98
+ # for m, mfrag in enumerate(self.frags):
99
+ # forces[mfrag] = np.cross(-zr[m], c3d[mfrag] - gs[m]) + zt[m]
100
+ # forces *= self.kappa
101
+ # # return zt, zr
102
+ # print("REF")
103
+ # print(forces)
104
+ # return {"energy": 1, "forces": forces.flatten()}
105
+
106
+ def get_forces(self, atoms, coords):
107
+ c3d = coords.reshape(-1, 3)
108
+
109
+ if len(self.pair_inds) == 0:
110
+ return {"energy": 1, "forces": np.zeros_like(coords)}
111
+
112
+ frag_coords = [c3d[frag] for frag in self.frags]
113
+ frag_centroids = np.array([c3d[frag].mean(axis=0) for frag in self.frags])
114
+ frag_centered = [
115
+ frag_coords[m] - frag_centroids[m] for m in range(self.frag_num)
116
+ ]
117
+ Hs = np.zeros(self.frag_num)
118
+
119
+ zt = np.zeros((self.frag_num, 3))
120
+ zr = np.zeros((self.frag_num, 3))
121
+ for (m, n), phi, avg_cov_radii in zip(
122
+ self.pair_inds, self.phis, self.avg_cov_radii
123
+ ):
124
+ mfrag = self.frags[m]
125
+ mcoords3d = c3d[mfrag]
126
+ ncoords3d = c3d[self.frags[n]]
127
+ coord_diffs = ncoords3d[None, :] - mcoords3d[:, None]
128
+ norms = np.linalg.norm(coord_diffs, axis=2)
129
+ H = norms < phi[:, None] * avg_cov_radii
130
+ H_sum = H.sum()
131
+ if H_sum == 0:
132
+ continue
133
+ Hs[m] += H_sum
134
+ y = (avg_cov_radii / norms - 1)[:, :, None] * coord_diffs
135
+ ynorms = np.linalg.norm(y, axis=2)
136
+ mcoords3d_centered = frag_centered[m]
137
+ dot = np.abs(np.einsum("ijk,ik->ij", y, mcoords3d_centered))
138
+ zt[m] += (H[:, :, None] * dot[:, :, None] * y / ynorms[:, :, None]).sum(
139
+ axis=(0, 1)
140
+ )
141
+ zr[m] += (H[:, :, None] * np.cross(y, mcoords3d_centered[:, None, :])).sum(
142
+ axis=(0, 1)
143
+ )
144
+ N = self.frag_sizes_sq * Hs
145
+ N_invs = np.divide(1, N, out=np.zeros_like(N), where=N != 0)
146
+ zt *= N_invs[:, None]
147
+ zr *= N_invs[:, None]
148
+
149
+ forces = np.zeros_like(c3d)
150
+ for m, mfrag in enumerate(self.frags):
151
+ forces[mfrag] = np.cross(-zr[m], frag_centered[m]) + zt[m]
152
+ forces *= self.kappa
153
+
154
+ return {"energy": 1, "forces": forces.flatten()}