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,37 @@
1
+ # [1] https://doi.org/10.1016/j.cplett.2021.138970
2
+ # The dynamical significance of valley-ridge inflection points
3
+ # Víctor J.García-Garrido, Stephen Wiggins
4
+
5
+ import numpy as np
6
+
7
+ from pysisyphus.calculators.AnaPotBase import AnaPotBase
8
+
9
+
10
+ class VRIPot(AnaPotBase):
11
+ def __init__(self, **kwargs):
12
+ VTS = 0.5
13
+ xs = 1.0
14
+ xi = 0.3265
15
+ A = 1.0
16
+ B = 1.0
17
+ C = 1.0
18
+ lim = 1.5
19
+ lims = (-lim, lim)
20
+ kwargs_ = {
21
+ "V_str": (
22
+ f"{VTS} / {xs}**4 * x**2 * (x**2 - 2*{xs}**2)"
23
+ f"+ {A}*y**2 * ({xi}-x) "
24
+ f"+ y**4 * ({B} + {C}*x)"
25
+ ),
26
+ "xlim": lims,
27
+ "ylim": lims,
28
+ "levels": np.linspace(-3 * VTS, 2 * VTS, 65),
29
+ # "minima": ((-1.05274, 1.02776, 0), (1.94101, 3.85427, 0)),
30
+ # "saddles": ((0.6117313, 1.4929732, 0.0),),
31
+ }
32
+ _ = kwargs_["V_str"]
33
+ kwargs_.update(kwargs)
34
+ super().__init__(**kwargs_)
35
+
36
+ def __str__(self):
37
+ return "VRIPot calculator"
@@ -0,0 +1,333 @@
1
+ from collections import OrderedDict
2
+ import itertools
3
+ import logging
4
+ from pathlib import Path
5
+ import shutil
6
+ import subprocess
7
+ import tempfile
8
+
9
+ import numpy as np
10
+ import pyparsing as pp
11
+
12
+ from pysisyphus.config import Config
13
+ from pysisyphus.helpers_pure import chunks
14
+
15
+
16
+ CIOVL="""mix_aoovl=ao_ovl
17
+ a_mo=mos.1
18
+ b_mo=mos.2
19
+ ncore={ncore}
20
+ a_det=dets.1
21
+ b_det=dets.2
22
+ a_mo_read=2
23
+ b_mo_read=2
24
+ """
25
+
26
+ CIOVL_NO_SAO="""ao_read=-1
27
+ same_aos=.true.
28
+ a_mo=mos.1
29
+ b_mo=mos.2
30
+ ncore={ncore}
31
+ a_det=dets.1
32
+ b_det=dets.2
33
+ a_mo_read=2
34
+ b_mo_read=2"""
35
+
36
+
37
+ class WFOWrapper:
38
+ logger = logging.getLogger("wfoverlap")
39
+ matrix_types = OrderedDict((
40
+ ("ovlp", "Overlap matrix"),
41
+ ("renorm", "Renormalized overlap matrix"),
42
+ ("ortho", "Orthonormalized overlap matrix")
43
+ ))
44
+
45
+ def __init__(self, occ_mo_num, virt_mo_num, conf_thresh=1e-3,
46
+ calc_number=0, out_dir="./", wfow_mem=8000,
47
+ ncore=0, debug=False):
48
+ try:
49
+ self.base_cmd = Config["wfoverlap"]["cmd"]
50
+ except KeyError:
51
+ self.log("WFOverlap cmd not found in ~/.pysisyphusrc!")
52
+ # Should correspond to the attribute of the parent calculator
53
+ self.calc_number = calc_number
54
+ self.name = f"WFOWrapper_{self.calc_number}"
55
+
56
+ self.conf_thresh = conf_thresh
57
+ self.out_dir = Path(out_dir).resolve()
58
+ self.wfow_mem = int(wfow_mem)
59
+ self.ncore = int(ncore)
60
+ self.debug = debug
61
+
62
+ self.log(f"Using -m {self.wfow_mem} for wfoverlap.")
63
+
64
+ self.mo_inds_list = list()
65
+ self.from_set_list = list()
66
+ self.to_set_list = list()
67
+ self.turbo_mos_list = list()
68
+
69
+ self.occ_mo_num = int(occ_mo_num)
70
+ self.virt_mo_num = int(virt_mo_num)
71
+ self.mo_num = self.occ_mo_num + self.virt_mo_num
72
+ self.base_det_str = "d"*self.occ_mo_num + "e"*self.virt_mo_num
73
+ self.fmt = "{: .10f}"
74
+
75
+ self.iter_counter = 0
76
+
77
+ @property
78
+ def conf_thresh(self):
79
+ return self._conf_thresh
80
+
81
+ @conf_thresh.setter
82
+ def conf_thresh(self, conf_thresh):
83
+ self._conf_thresh = conf_thresh
84
+ self.log(f"Set CI-coeff threshold to {self.conf_thresh:.4e}")
85
+
86
+ def log(self, message):
87
+ self.logger.debug(f"{self.name}, " + message)
88
+
89
+ def fake_turbo_mos(self, mo_coeffs):
90
+ """Create a mos file suitable for TURBOMOLE input. All MO eigenvalues
91
+ are set to 0.0. There is also a little deviation in the formatting
92
+ (see turbo_fmt()) but it works ..."""
93
+
94
+ def turbo_fmt(num):
95
+ """Not quite the real TURBOMOLE format, but it works ...
96
+ In TURBOMOLE the first character is always 0 for positive doubles
97
+ and - for negative doubles."""
98
+ return f"{num:+20.13E}".replace("E", "D")
99
+
100
+ base = "$scfmo scfconv=7 format(4d20.14)\n# from pysisyphus\n" \
101
+ "{mo_strings}\n$end"
102
+
103
+ # WFOverlap expects the string eigenvalue starting at 16, so we have
104
+ mo_str = "{mo_index:>6d} a eigenvalue=-.00000000000000D+00 " \
105
+ "nsaos={nsaos}\n{joined}"
106
+ nsaos = mo_coeffs.shape[0]
107
+
108
+ mo_strings = list()
109
+ for mo_index, mo in enumerate(mo_coeffs, 1):
110
+ in_turbo_fmt = [turbo_fmt(c) for c in mo]
111
+ # Combine into chunks of four
112
+ lines = ["".join(chnk) for chnk in chunks(in_turbo_fmt, 4)]
113
+ # Join the lines
114
+ joined = "\n".join(lines)
115
+ mo_strings.append(mo_str.format(mo_index=mo_index, nsaos=nsaos,
116
+ joined=joined))
117
+ return base.format(mo_strings="\n".join(mo_strings))
118
+
119
+ def ci_coeffs_above_thresh(self, ci_coeffs, thresh=None):
120
+ # Drop unimportant configurations, that are configurations
121
+ # having low weights in all states under consideration.
122
+ if thresh is None:
123
+ thresh = self.conf_thresh
124
+ mo_inds = np.where(np.abs(ci_coeffs) >= thresh)
125
+ return mo_inds
126
+
127
+ def make_det_string(self, inds):
128
+ """Return spin adapted strings."""
129
+ from_mo, to_mo = inds
130
+ # Until now the first virtual MO (to_mo) has index 0. To subsitute
131
+ # the base_str at the correct index we have to increase all to_mo
132
+ # indices by the number off occupied MO.
133
+ to_mo += self.occ_mo_num
134
+ # Make string for excitation of an alpha electron
135
+ ab = list(self.base_det_str)
136
+ ab[from_mo] = "b"
137
+ ab[to_mo] = "a"
138
+ ab_str = "".join(ab)
139
+ # Make string for excitation of an beta electron
140
+ ba = list(self.base_det_str)
141
+ ba[from_mo] = "a"
142
+ ba[to_mo] = "b"
143
+ ba_str = "".join(ba)
144
+ return ab_str, ba_str
145
+
146
+ def generate_all_dets(self, occ_set1, virt_set1, occ_set2, virt_set2):
147
+ """Generate all possible single excitation determinant strings
148
+ from union(occ_mos) to union(virt_mos)."""
149
+ # Unite the respective sets of both calculations
150
+ occ_set = occ_set1 | occ_set2
151
+ virt_set = virt_set1 | virt_set2
152
+ # Genrate all possible excitations (combinations) from the occupied
153
+ # MO set to (and) the virtual MO set.
154
+ all_inds = [(om, vm) for om, vm
155
+ in itertools.product(occ_set, virt_set)]
156
+ det_strings = [self.make_det_string(inds) for inds in all_inds]
157
+ return all_inds, det_strings
158
+
159
+ def make_full_dets_list(self, all_inds, det_strings, ci_coeffs):
160
+ dets_list = list()
161
+ for inds, det_string in zip(all_inds, det_strings):
162
+ ab, ba = det_string
163
+ from_mo, to_mo = inds
164
+ per_state = ci_coeffs[:,from_mo,to_mo]
165
+ if (np.abs(per_state) < self.conf_thresh).all():
166
+ continue
167
+ # A singlet determinant can be formed in two ways:
168
+ # (up down) (up down) (up down) ...
169
+ # or
170
+ # (down up) (down up) (down up) ...
171
+ # We take this into account by expanding the singlet determinants
172
+ # and using a proper normalization constant.
173
+ # See 10.1063/1.3000012 Eq. (5) and 10.1021/acs.jpclett.7b01479 SI
174
+ # and "Principles of Molecular Photochemistry: An Introduction",
175
+ # Section 2.27 Vector model of Two Coupled Electron Spins, p. 91-92
176
+ per_state *= 1/(2**0.5)
177
+ as_str = lambda arr: " ".join([self.fmt.format(cic)
178
+ for cic in arr])
179
+ ps_str = as_str(per_state)
180
+ mps_str = as_str(-per_state)
181
+ dets_list.append(f"{ab}\t{ps_str}")
182
+ dets_list.append(f"{ba}\t{mps_str}")
183
+ return dets_list
184
+
185
+ def set_from_nested_list(self, nested):
186
+ return set([i for i in itertools.chain(*nested)])
187
+
188
+ def make_dets_header(self, cic, dets_list):
189
+ return f"{len(cic)} {self.mo_num} {len(dets_list)}"
190
+
191
+ def parse_wfoverlap_out(self, text, type_="ortho"):
192
+ """Returns overlap matrix."""
193
+ header_str = self.matrix_types[type_] + " <PsiA_i|PsiB_j>"
194
+ header = pp.Literal(header_str)
195
+ float_ = pp.Word(pp.nums+"-.")
196
+ psi_bra = pp.Literal("<Psi") + pp.Word(pp.alphas) \
197
+ + pp.Word(pp.nums) + pp.Literal("|")
198
+ psi_ket = pp.Literal("|Psi") + pp.Word(pp.alphas) \
199
+ + pp.Word(pp.nums) + pp.Literal(">")
200
+ matrix_line = pp.Suppress(psi_bra) + pp.OneOrMore(float_)
201
+
202
+ # I really don't know why this is needed but otherwise I can't parse
203
+ # overlap calculations with the true AO overlap matrix, even though
204
+ # the files appear completely similar regarding printing of the matrices.
205
+ # WTF. WTF!
206
+ text = text.replace("\n", " ")
207
+ parser = pp.SkipTo(header, include=True) \
208
+ + pp.OneOrMore(psi_ket) \
209
+ + pp.OneOrMore(matrix_line).setResultsName("overlap")
210
+
211
+ result = parser.parseString(text)
212
+
213
+ return np.array(list(result["overlap"]), dtype=np.float64)
214
+
215
+ def get_from_to_sets(self, ci_coeffs):
216
+ all_mo_inds = [self.ci_coeffs_above_thresh(per_state)
217
+ for per_state in ci_coeffs]
218
+
219
+ from_mos, to_mos = zip(*all_mo_inds)
220
+ from_set = self.set_from_nested_list(from_mos)
221
+ to_set = self.set_from_nested_list(to_mos)
222
+
223
+ return from_set, to_set
224
+
225
+ def get_gs_line(self, ci_coeffs_with_gs):
226
+ gs_coeffs = np.zeros(len(ci_coeffs_with_gs))
227
+ # Ground state is 100% HF configuration
228
+ gs_coeffs[0] = 1
229
+ gs_coeffs_str = " ".join([self.fmt.format(c)
230
+ for c in gs_coeffs])
231
+ gs_line = f"{self.base_det_str}\t{gs_coeffs_str}"
232
+ return gs_line
233
+
234
+ def wf_overlap(self, cycle1, cycle2, ao_ovlp=None):
235
+ mos1, cic1 = cycle1
236
+ mos2, cic2 = cycle2
237
+
238
+ fs1, ts1 = self.get_from_to_sets(cic1)
239
+ fs2, ts2 = self.get_from_to_sets(cic2)
240
+
241
+ # Create a fake array for the ground state where all CI coefficients
242
+ # are zero and add it.
243
+ gs_cic = np.zeros_like(cic1[0])
244
+ cic1_with_gs = np.concatenate((gs_cic[None,:,:], cic1))
245
+ cic2_with_gs = np.concatenate((gs_cic[None,:,:], cic2))
246
+
247
+ all_inds, det_strings = self.generate_all_dets(fs1, ts1, fs2, ts2)
248
+ # Prepare lines for ground state
249
+ gs_line1 = self.get_gs_line(cic1_with_gs)
250
+ gs_line2 = self.get_gs_line(cic2_with_gs)
251
+ dets1 = [gs_line1] + self.make_full_dets_list(all_inds,
252
+ det_strings,
253
+ cic1_with_gs)
254
+ dets2 = [gs_line2] + self.make_full_dets_list(all_inds,
255
+ det_strings,
256
+ cic2_with_gs)
257
+ header1 = self.make_dets_header(cic1_with_gs, dets1)
258
+ header2 = self.make_dets_header(cic2_with_gs, dets2)
259
+
260
+ backup_path = self.out_dir / f"wfo_{self.calc_number}.{self.iter_counter:03d}"
261
+ with tempfile.TemporaryDirectory() as tmp_dir:
262
+ tmp_path = Path(tmp_dir)
263
+ self.log(f"Calculation in {tmp_dir}")
264
+ # Write fake TURBOMOLE mo files
265
+ for i, mos in enumerate((mos1, mos2), 1):
266
+ turbo_mos = self.fake_turbo_mos(mos)
267
+ with open(tmp_path / f"mos.{i}", "w") as handle:
268
+ handle.write(turbo_mos)
269
+ dets1_path = tmp_path / "dets.1"
270
+ with open(dets1_path, "w") as handle:
271
+ handle.write(header1+"\n"+"\n".join(dets1))
272
+ dets2_path = tmp_path / "dets.2"
273
+ with open(dets2_path, "w") as handle:
274
+ handle.write(header2+"\n"+"\n".join(dets2))
275
+
276
+ # Decide wether to use a double molecule overlap matrix or
277
+ # (approximately) reconstruct the ao_ovlp matrix from the MO
278
+ # coefficients.
279
+ if ao_ovlp is None:
280
+ ciovl_in = CIOVL_NO_SAO
281
+ self.log("Got no ao_ovl-matrix. Using ao_read=-1 and "
282
+ "same_aos=.true. to reconstruct the AO-overlap matrix!")
283
+ else:
284
+ ciovl_in = CIOVL
285
+ ao_header = "{} {}".format(*ao_ovlp.shape)
286
+ ao_ovl_path = tmp_path / "ao_ovl"
287
+ np.savetxt(ao_ovl_path, ao_ovlp, fmt="%22.15E", header=ao_header,
288
+ comments="")
289
+
290
+ ciovl_in_rendered = ciovl_in.format(ncore=self.ncore)
291
+ ciovl_fn = "ciovl.in"
292
+ with open(tmp_path / ciovl_fn, "w") as handle:
293
+ handle.write(ciovl_in_rendered)
294
+
295
+ # Create a backup of the whole temporary directory
296
+ try:
297
+ shutil.rmtree(backup_path)
298
+ except FileNotFoundError:
299
+ pass
300
+ shutil.copytree(tmp_dir, backup_path)
301
+
302
+ # Currently, debug==True crashes the subsequent parsing
303
+ debug_str = "--debug" if self.debug else ""
304
+ cmd = f"{self.base_cmd} -m {self.wfow_mem} -f {ciovl_fn} {debug_str}".split()
305
+ result = subprocess.Popen(cmd, cwd=tmp_path,
306
+ stdout=subprocess.PIPE)
307
+ result.wait()
308
+ stdout = result.stdout.read().decode("utf-8")
309
+ self.iter_counter += 1
310
+ if "differs significantly" in stdout:
311
+ self.log("WARNING: Orthogonalized matrix differs significantly "
312
+ "from original matrix! There is probably mixing with "
313
+ "external states.")
314
+
315
+ wfo_log_fn = self.out_dir / f"wfo_{self.calc_number}.{self.iter_counter:03d}.out"
316
+ with open(wfo_log_fn, "w") as handle:
317
+ handle.write(stdout)
318
+ # Also copy the WFO-output to the input backup
319
+ shutil.copy(wfo_log_fn, backup_path)
320
+
321
+ matrices = [self.parse_wfoverlap_out(stdout, type_=key)
322
+ for key in self.matrix_types.keys()]
323
+
324
+ reshaped_mats = [mat.reshape(-1, len(cic2_with_gs))
325
+ for mat in matrices]
326
+ for key, mat in zip(self.matrix_types.keys(), reshaped_mats):
327
+ mat_fn = backup_path / f"{key}_mat.dat"
328
+ np.savetxt(mat_fn, mat)
329
+
330
+ return reshaped_mats
331
+
332
+ def __str__(self):
333
+ return self.name