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,150 @@
1
+ import glob
2
+ import os
3
+
4
+ import numpy as np
5
+ import pyparsing as pp
6
+ import re
7
+
8
+
9
+ def to_float(s, loc, toks):
10
+ match = toks[0].replace("D", "E")
11
+ return float(match)
12
+
13
+
14
+ def make_float_class(**kwargs):
15
+ return pp.Word(pp.nums + ".-DE+", **kwargs).setParseAction(to_float)
16
+
17
+
18
+ def parse_turbo_gradient(path):
19
+ results = {}
20
+ gradient_fn = glob.glob(os.path.join(path, "gradient"))
21
+ if not gradient_fn:
22
+ raise Exception("gradient file not found!")
23
+ assert len(gradient_fn) == 1
24
+ gradient_fn = gradient_fn[0]
25
+ with open(gradient_fn) as handle:
26
+ text = handle.read()
27
+
28
+ float_ = make_float_class()
29
+ cycle = pp.Word(pp.nums).setResultsName("cycle")
30
+ scf_energy = float_.setResultsName("scf_energy")
31
+ grad_norm = float_.setResultsName("grad_norm")
32
+ float_line = float_ + float_ + float_
33
+ coord_line = pp.Group(float_line + pp.Word(pp.alphas))
34
+ grad_line = pp.Group(float_line)
35
+ cart_grads = pp.Literal("cartesian gradients")
36
+ energy_type = pp.Or(
37
+ (
38
+ pp.Literal("SCF energy"),
39
+ pp.Literal("ex. state energy"),
40
+ pp.Literal("CC2 energy"),
41
+ pp.Literal("ADC(2) energy"),
42
+ pp.Literal("MP2 energy"),
43
+ )
44
+ )
45
+
46
+ parser = (
47
+ pp.Or((pp.Literal("$grad"), pp.Literal("$gradient")))
48
+ + pp.Optional(cart_grads)
49
+ + pp.Literal("cycle =")
50
+ + cycle
51
+ + energy_type
52
+ + pp.Literal("=")
53
+ + scf_energy
54
+ + pp.Literal("|dE/dxyz| =")
55
+ + grad_norm
56
+ + pp.OneOrMore(coord_line).setResultsName("coords")
57
+ + pp.OneOrMore(grad_line).setResultsName("grad")
58
+ + pp.Literal("$end")
59
+ )
60
+ parsed = parser.parseString(text)
61
+ gradient = np.array(parsed["grad"].asList()).flatten()
62
+
63
+ results["energy"] = parsed["scf_energy"]
64
+ results["forces"] = -gradient
65
+ return results
66
+
67
+
68
+ def parse_turbo_ccre0_ascii(text):
69
+ float_ = make_float_class()
70
+ float_20 = make_float_class(exact=20)
71
+ int_ = pp.Word(pp.nums).setParseAction(lambda s, loc, toks: int(toks[0]))
72
+
73
+ title = pp.Literal("$CCRE0-") + pp.Word(pp.nums + "-")
74
+ method = pp.Word(pp.alphanums + "()") + float_ + float_ + int_ + int_ + int_
75
+ data = pp.Group(pp.OneOrMore(float_20))
76
+ end = pp.Literal("$end")
77
+
78
+ parser = title + method + data.setResultsName("data") + end
79
+ result = parser.parseString(text)
80
+ data = np.array(result["data"].asList())
81
+ return data
82
+
83
+
84
+ def parse_turbo_mos(text):
85
+ float_20 = make_float_class(exact=20)
86
+ int_ = pp.Word(pp.nums)
87
+ comment = pp.Literal("#") + pp.restOfLine
88
+
89
+ mo_num = int_
90
+ sym = pp.Word(pp.alphanums)
91
+ eigenvalue = pp.Literal("eigenvalue=") + float_20
92
+ nsaos = pp.Literal("nsaos=") + int_
93
+ mo_coeffs = pp.OneOrMore(float_20)
94
+
95
+ mo = pp.Group(
96
+ mo_num + sym + eigenvalue + nsaos + mo_coeffs.setResultsName("mo_coeffs")
97
+ )
98
+
99
+ parser = (
100
+ pp.Literal("$scfmo")
101
+ + pp.Literal("scfconv=")
102
+ + pp.Word(pp.nums)
103
+ + pp.Literal("format(4d20.14) ")
104
+ + pp.ZeroOrMore(comment)
105
+ + pp.OneOrMore(mo).setResultsName("mos")
106
+ + pp.Literal("$end")
107
+ )
108
+ parsed = parser.parseString(text)
109
+ mo_coeffs = np.array([mo.mo_coeffs.asList() for mo in parsed.mos]).T
110
+
111
+ # MOs are in columns
112
+ return mo_coeffs
113
+
114
+
115
+ def parse_turbo_exstates(text):
116
+ """Parse excitation energies (first blocks) from an exstates file."""
117
+ float_ = make_float_class()
118
+ exc_energies_line = (
119
+ pp.Literal("$excitation_energies_")
120
+ + pp.Word(pp.alphanums + "()").setResultsName("model")
121
+ + pp.Word("_")
122
+ + pp.restOfLine
123
+ )
124
+ exc_energy = pp.Suppress(pp.Word(pp.nums)) + float_
125
+ exc_energies_block = pp.Group(
126
+ exc_energies_line + pp.Group(pp.OneOrMore(exc_energy)).setResultsName("exc_ens")
127
+ )
128
+
129
+ parser = pp.OneOrMore(exc_energies_block).setResultsName("exc_blocks")
130
+ result = parser.parseString(text)
131
+ exc_energies_by_model = [(b.model, b.exc_ens.asList()) for b in result.exc_blocks]
132
+ return exc_energies_by_model
133
+
134
+
135
+ def parse_turbo_exstates_re(text):
136
+ results = dict()
137
+ exc_ens_str = "excitation_energies_"
138
+ model_re = re.compile(exc_ens_str + r"(\w+?)_")
139
+ blocks = text.strip().split("$")
140
+ for block in blocks:
141
+ if not block.startswith(exc_ens_str):
142
+ continue
143
+ model_line, *exc_lines = block.strip().split("\n")
144
+ mobj = model_re.search(model_line)
145
+ model = mobj.group(1)
146
+ exc_lines = [line.strip().split() for line in exc_lines]
147
+ assert all([len(line) == 2 for line in exc_lines])
148
+ exc_ens = np.array([exc_en for _, exc_en in exc_lines], dtype=float)
149
+ results[model] = exc_ens
150
+ return results
pysisyphus/color.py ADDED
@@ -0,0 +1,19 @@
1
+ def red(str_):
2
+ return f"\033[91m{str_}\033[0m"
3
+
4
+
5
+ def green(str_):
6
+ return f"\033[92m{str_}\033[0m"
7
+
8
+
9
+ BOOL_COLORS = {
10
+ True: green,
11
+ False: red,
12
+ }
13
+
14
+
15
+ def bool_color(bool_, str_=None):
16
+ if str_ is None:
17
+ str_ = str(bool_)
18
+ color = BOOL_COLORS[bool_]
19
+ return color(str_)
pysisyphus/config.py ADDED
@@ -0,0 +1,133 @@
1
+ import argparse
2
+ import configparser
3
+ from io import StringIO
4
+ import os
5
+ from pathlib import Path
6
+ import shutil
7
+ import sys
8
+ import tempfile
9
+
10
+
11
+ from pysisyphus import logger
12
+
13
+
14
+ CONFIG_DIR = Path(os.path.abspath(os.path.dirname(__file__)))
15
+ BASIS_LIB_DIR = Path(CONFIG_DIR / "basis_library")
16
+ LIB_DIR = Path(CONFIG_DIR / "geom_library")
17
+ WF_LIB_DIR = Path(CONFIG_DIR / "wf_library")
18
+ T_DEFAULT = 298.15 # Kelvin
19
+ p_DEFAULT = 101325 # Pascal
20
+ OUT_DIR_DEFAULT = str(Path(tempfile.gettempdir()) / "qm_calcs")
21
+ BEND_MIN_DEG = 15
22
+ LB_MIN_DEG = 175
23
+ DIHED_MAX_DEG = 175
24
+ L_MAX = 4
25
+ L_AUX_MAX = 5
26
+ AFIR_RMSD_THRESH = 0.25
27
+ DEFAULTS = {
28
+ # .pysisyphusrc key: command
29
+ "mwfn": "Multiwfn",
30
+ "jmol": "jmol",
31
+ "packmol": "packmol",
32
+ "formchk": "formchk",
33
+ "unfchk": "unfchk",
34
+ "rwfdump": "rwfdump",
35
+ # QC codes
36
+ "orca": "orca",
37
+ "orca5": "orca",
38
+ "gaussian16": "g16",
39
+ "wfoverlap": "wfoverlap.x",
40
+ "openmolcas": "pymolcas",
41
+ "gamess": "rungms",
42
+ "xtb": "xtb",
43
+ "mopac": "mopac",
44
+ }
45
+
46
+
47
+ # First try to read path to .pysisyphusrc from environment variable
48
+ try:
49
+ pysisrc_env = os.getenv("PYSISRC", default=None)
50
+ config_fn = Path(pysisrc_env).resolve()
51
+ print(f"Read pysisyphus configuration from '{config_fn}'")
52
+ # Fallback to $HOME/.pysisyphusrc
53
+ except TypeError:
54
+ config_fn = Path.home() / ".pysisyphusrc"
55
+
56
+ if not config_fn.is_file():
57
+ print(f"Couldn't find configuration file. Expected it at '{config_fn}'.")
58
+
59
+ Config = configparser.ConfigParser()
60
+ read_fns = Config.read(config_fn)
61
+
62
+
63
+ def get_cmd(section, key="cmd", use_defaults=True):
64
+ cmd = None
65
+ msg = f" and no default was specified for '{section}'."
66
+
67
+ # First we try to load the command from .pysisyphusrc
68
+ try:
69
+ cmd = Config[section][key]
70
+ msg = "."
71
+ # When the command is not available on .pysisyphusrc we check the defaults
72
+ except KeyError:
73
+ if use_defaults:
74
+ default_key = section if key == "cmd" else key
75
+ try:
76
+ default_cmd = DEFAULTS[default_key]
77
+ cmd = shutil.which(default_cmd)
78
+ # 'msg' will only be printed when 'cmd' is None, so the msg is
79
+ # always negative.
80
+ msg = f" and default cmd='{default_cmd}' was not found in $PATH."
81
+ except KeyError:
82
+ pass
83
+
84
+ if cmd is None:
85
+ logger.warning(
86
+ f"Failed to load '{key}' from [{section}] "
87
+ f"in ~/.pysisyphusrc{msg}"
88
+ )
89
+ cmd = None
90
+ return cmd
91
+
92
+
93
+ def detect_paths():
94
+ config = configparser.ConfigParser()
95
+
96
+ for k, v in DEFAULTS.items():
97
+ print(f"{k: >16}: ... ", end="")
98
+ if not (path := shutil.which(v)):
99
+ print("not found.")
100
+ else:
101
+ path = Path(path).resolve()
102
+ config[k] = {"cmd": str(path)}
103
+ print(path)
104
+
105
+ fp = StringIO()
106
+ config.write(fp, space_around_delimiters=False)
107
+ fp.seek(0)
108
+ config_text = fp.read()
109
+ return config_text
110
+
111
+
112
+ def parse_args(args):
113
+ parser = argparse.ArgumentParser()
114
+
115
+ parser.add_argument(
116
+ "--out", "-o", help="Filename to which the detected cmds are dumped."
117
+ )
118
+
119
+ return parser.parse_args(args)
120
+
121
+
122
+ def run_detect_paths():
123
+ args = parse_args(sys.argv[1:])
124
+ out = args.out
125
+
126
+ config_text = detect_paths()
127
+ if out:
128
+ print("Dumped detected cmds to '{out}'")
129
+ with open(out, "w") as handle:
130
+ handle.write(config_text)
131
+ else:
132
+ print("\nExample .pysisyphusrc:\n")
133
+ print(config_text)
@@ -0,0 +1,65 @@
1
+ import scipy.constants as spc
2
+
3
+ PI = spc.pi
4
+
5
+ # Speed of light in m/s
6
+ C = spc.c
7
+ # Speed of light in atomic units
8
+ CAU = spc.value("inverse fine-structure constant")
9
+ # ħ = h / 2π in J/s
10
+ HBAR = spc.hbar
11
+ # h
12
+ PLANCK = spc.Planck
13
+ PLANCKAU = 2 * spc.pi # With ħ_au = 1 and ħ_au=h_au/2π -> h_au = 2π
14
+ # Conversion factor for momentum in SI to atomic units
15
+ P_AU = spc.value("atomic unit of momentum")
16
+
17
+ # Bohr radius in m
18
+ BOHR2M = spc.value("Bohr radius")
19
+ # Bohr -> Å conversion factor
20
+ BOHR2ANG = BOHR2M * 1e10
21
+ # Å -> Bohr conversion factor
22
+ ANG2BOHR = 1 / BOHR2ANG
23
+ # Hartree to J
24
+ AU2J = spc.value("Hartree energy")
25
+ # Hartree to kJ / mol
26
+ AU2KJPERMOL = AU2J / 1000 * spc.Avogadro
27
+ # Hartree to kcal mol⁻¹
28
+ AU2KCALPERMOL = AU2KJPERMOL / spc.calorie
29
+ # Hartree to eV
30
+ AU2EV = spc.value("Hartree energy in eV")
31
+ # Joule to eV
32
+ JOULE2EV = AU2EV / AU2J
33
+ # Wavenumber to Hartree
34
+ NU2AU = spc.h * C * 1e2 / AU2J
35
+ # eV/Å -> Hartree/Bohr
36
+ EVANG2AUBOHR = 1 / AU2EV / ANG2BOHR
37
+ # fs -> Bohr * sqrt(amu/Hartree)
38
+ FS2AU = 0.9682885864793366
39
+ # Boltzman constant, (m² kg s⁻² K⁻¹) or just (J / K)
40
+ KB = spc.Boltzmann
41
+ KBAU = KB / AU2J
42
+ # Ideal gas constant
43
+ R = spc.gas_constant
44
+ # Atomic unit of time to second
45
+ AU2SEC = spc.value("atomic unit of time")
46
+ # Atomic mass unit to kg
47
+ AMU2KG = spc.value("atomic mass constant")
48
+ M_E = spc.electron_mass
49
+ AMU2AU = AMU2KG / M_E
50
+ # Avogadro constant
51
+ NA = spc.Avogadro
52
+
53
+ ##############
54
+ # MD related #
55
+ ##############
56
+
57
+ # Force/amu to acceleration
58
+ # Hartree/(Bohr*amu) -> Bohr / fs²
59
+ FORCE2ACC = AU2J / (AMU2KG * BOHR2M**2 * 1e30)
60
+ # Velocity*amu -> Energy
61
+ # Bohr²/fs²*amu -> Hartree
62
+ # VELO2E = AMU2KG * BOHR2M**2 / (1e-30 * AU2J)
63
+ VELO2E = 1 / FORCE2ACC
64
+ # Velocity from Bohr/fs to Bohr/t_atomic_unit
65
+ BOHRPERFS2AU = AU2SEC * 1e15
@@ -0,0 +1,230 @@
1
+ # [1] https://aip.scitation.org/doi/pdf/10.1063/1.1495401
2
+ # [2] http://dx.doi.org/10.1063/1.4962019
3
+ # Zhang, 2016
4
+ # FreeEnd Adaptive NEB
5
+
6
+ # See /scratch/projekte/biaryl/me_cn/cycloadd22/guess01/neb2
7
+
8
+ import numpy as np
9
+
10
+ from pysisyphus.cos.NEB import NEB
11
+ from pysisyphus.interpolate import interpolate
12
+
13
+
14
+ class AdaptiveNEB(NEB):
15
+
16
+ def __init__(self, images, adapt=True, adapt_fact=.25, adapt_between=1,
17
+ scale_fact=False, keep_hei=True, free_ends=True,
18
+ **kwargs):
19
+ """(Free-End) Adaptive Nudged Elastic Band.
20
+
21
+ Parameters
22
+ ----------
23
+ images : list of Geometry objects
24
+ Images of the band.
25
+ adapt : bool, default True
26
+ Whether to adapt the image number or not. This switch is included
27
+ to support the FreeEndNEB class, that is just a thin wrapper around
28
+ this class.
29
+ adapt_fact : positive float
30
+ Factor that is used to decide wether to adapt. The inital
31
+ threshold is calculated by multiplying the RMS force of the
32
+ band with this factor. When the RMS of the force falls
33
+ below this threshold adaption takes place.
34
+ adapat_between : positive integer
35
+ Number of images to interpolate between the highest energy
36
+ image and its neighbours. The number of starting images
37
+ must be higher or equal then 2*adapt_between+3, as we
38
+ reuse/transfer the calculators from the starting images onto
39
+ the new ones.
40
+ scale_fact : bool, default False
41
+ Whether to increase adapt_fact in deeper levels. This may lead
42
+ to earlier adapation.
43
+ keep_hei : bool, optional
44
+ Whether to keep the highest energy image (usually a very good
45
+ idea) or to interpolate only between the neighbouring images.
46
+ free_ends : bool, default True
47
+ Whether to use modified forces on the end images.
48
+ """
49
+ super().__init__(images, **kwargs)
50
+
51
+ self.adapt = adapt
52
+ self.adapt_fact = adapt_fact
53
+ self.adapt_between = adapt_between
54
+ self.scale_fact = scale_fact
55
+ self.keep_hei = keep_hei
56
+ self.free_ends = free_ends
57
+
58
+ self.adapt_thresh = None
59
+ self.level = 1
60
+ self.coords_backup = list()
61
+
62
+ @NEB.forces.getter
63
+ def forces(self):
64
+ """See Eq. (7) in [2]."""
65
+
66
+ forces = super().forces
67
+ forces_size = self.images[-1].forces.size
68
+
69
+ if self.free_ends and (not self.fix_first):
70
+ mod_forces = self.get_perpendicular_forces(0)
71
+ forces[:forces_size] = mod_forces
72
+
73
+ if self.free_ends and (not self.fix_last):
74
+ mod_forces = self.get_perpendicular_forces(self.last_index)
75
+ forces[-forces_size:] = mod_forces
76
+
77
+ self._forces = forces
78
+ return self._forces
79
+
80
+ def update_adapt_thresh(self, forces):
81
+ """Update the adaption threshold.
82
+
83
+ Parameters
84
+ ----------
85
+ forces : np.array
86
+ Forces of the previous optimization cycle.
87
+ """
88
+ old_thresh = self.adapt_thresh
89
+
90
+ # Dividing by (1 / level)**1/2 scales the adapt_fact as
91
+ # level 1: 1. (No scaling)
92
+ # level 2: 1.414
93
+ # level 3: 1.732
94
+ # level 4: 2.
95
+ # level 5: 2.236
96
+ # ...
97
+ # This ensures that the adapt_fact increases as we recurse
98
+ # deeper.
99
+ if self.scale_fact:
100
+ self.adapt_thresh = (self.rms(forces) * self.adapt_fact
101
+ / np.sqrt(1 / self.level)
102
+ )
103
+ else:
104
+ self.adapt_thresh = self.rms(forces) * self.adapt_fact
105
+ #arr / np.sqrt(1/np.arange(1, 6))
106
+ self.log(f"Updating adapt_thres. Old thresh was {old_thresh:}. "
107
+ f"New threshold is {self.adapt_thresh:.03f}")
108
+
109
+ def adapt_this_cycle(self, forces):
110
+ """Decide wether to adapt.
111
+
112
+ Parameters
113
+ ----------
114
+ forces : np.array
115
+ Forces of the previous optimization cycle.
116
+
117
+ Returns
118
+ -------
119
+ adapt : bool
120
+ Flag that indicates if adaption should take place in this cycle.
121
+ """
122
+ cur_rms = self.rms(forces)
123
+ adapt = cur_rms <= self.adapt_thresh
124
+ self.log(f"Current RMS of forces is {cur_rms:03f}. Current thresh "
125
+ f"{self.adapt_thresh:03f}. Adapt = {adapt}")
126
+ return adapt
127
+
128
+ def prepare_opt_cycle(self, *args, **kwargs):
129
+ """Check for adaption and adapt if needed.
130
+
131
+ See ChainOfStates.prepare_opt_cycle for a complete docstring.
132
+ """
133
+ base_reset = super().prepare_opt_cycle(*args, **kwargs)
134
+ if not self.adapt:
135
+ return base_reset
136
+
137
+ # Transferring Calculators including WFOWrapper objects
138
+ # in excited state calculations may be problematic.
139
+ # A problem would be the interpolation between two images with
140
+ # different roots. What root should be taken for the interpolated
141
+ # image? Additionally we probably would have to shift around the
142
+ # iterations stored in the WFOWrapper.
143
+ img0 = self.images[0]
144
+ if hasattr(img0, "track") and (img0.track == True):
145
+ raise Exception(
146
+ "track = True and interpolating new images "
147
+ "may give problems with excited state tracking, so this "
148
+ "is disabled for now."
149
+ )
150
+
151
+ # Initialize adapt_thresh
152
+ if not self.adapt_thresh:
153
+ self.update_adapt_thresh(self.forces_list[-1])
154
+
155
+ if not self.adapt_this_cycle(self.forces_list[-1]):
156
+ return base_reset
157
+
158
+ #
159
+ # Adapation from here on
160
+ #
161
+ # Backup coords if we have to step back
162
+ self.coords_backup.append(self.coords)
163
+ # Determine highest energy index and image (HEI)
164
+ hei_index = self.get_hei_index(self.all_energies[-1])
165
+ self.log(f"Index of highest energy image is {hei_index}")
166
+ if (hei_index == 0) or (hei_index == len(self.images)-1):
167
+ self.log("Cant adapt, HEI is first or last!")
168
+ return base_reset
169
+ else:
170
+ self.fix_first = False
171
+ self.fix_last = False
172
+ self.log("First and last image are now free to move.")
173
+ prev_index = hei_index - 1
174
+ next_index = hei_index + 1
175
+ prev_image = self.images[prev_index]
176
+ hei_image = self.images[hei_index]
177
+ next_image = self.images[next_index]
178
+
179
+ # Two interpolations
180
+ # prev. neighbour - HEI
181
+ # HEI - next neighbour
182
+ # Usually the better idea
183
+ kwargs = {
184
+ "kind": "lst",
185
+ "only_between": True,
186
+ "interpol_kwargs": {"silent": True},
187
+ }
188
+ if self.keep_hei:
189
+ # Interpolation of new images between previous neighbour
190
+ # and the HEI.
191
+ kwargs["between"] = self.adapt_between
192
+ new_images_1 = interpolate(prev_image, hei_image, **kwargs)
193
+ new_images_2 = interpolate(hei_image, next_image, **kwargs)
194
+ # Between next neighbour and the HEI.
195
+ all_new_images = ([prev_image] + new_images_1
196
+ + [hei_image]
197
+ + new_images_2 + [next_image])
198
+ # One interpolation
199
+ # prev. neighbour - next neighbour
200
+ else:
201
+ kwargs["between"] = 2*self.adapt_between+1
202
+ new_images = interpolate(prev_image, next_image, **kwargs)
203
+ all_new_images = [prev_image] + new_images + [next_image]
204
+
205
+ assert len(all_new_images) <= len(self.images), \
206
+ f"The number of new images ({len(all_new_images)}) is smaller than " \
207
+ f"the number of current images ({len(self.images)}). Increase the number " \
208
+ "of starting images or decrease 'adapt_between'."
209
+ self.level += 1
210
+
211
+ print(f"Adapted images! New number of images is {len(all_new_images)}. "
212
+ f"Current level is {self.level}.")
213
+
214
+ # Backup old calculators
215
+ calcs = [img.calculator for img in self.images]
216
+ # Get numbered indices of the current calcs, so we can continue with
217
+ # higher numbers for the new images.
218
+ calc_numbers = [calc.calc_number for calc in calcs]
219
+ new_calc_number_start = max(calc_numbers) + 1
220
+ # Transfer calculators to the new images
221
+ for i, (new_image, calc) in enumerate(zip(all_new_images, calcs)):
222
+ calc.calc_number = new_calc_number_start + i
223
+ new_image.set_calculator(calc)
224
+ self.images = all_new_images
225
+ self.set_zero_forces_for_fixed_images()
226
+
227
+ # Reset adapt_thresh so it will be set again in the beginning
228
+ # of the next iteration.
229
+ self.adapt_thresh = None
230
+ return True