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,341 @@
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 h5py
10
+ import numpy as np
11
+ import pyparsing as pp
12
+
13
+ from pysisyphus.config import Config
14
+ from pysisyphus.helpers_pure import chunks
15
+
16
+
17
+ CIOVL="""mix_aoovl=ao_ovl
18
+ a_mo=mos.1
19
+ b_mo=mos.2
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
+ a_det=dets.1
31
+ b_det=dets.2
32
+ a_mo_read=2
33
+ b_mo_read=2"""
34
+
35
+
36
+ class WFOWrapper2:
37
+ logger = logging.getLogger("wfoverlap")
38
+ matrix_types = OrderedDict((
39
+ ("ovlp", "Overlap matrix"),
40
+ ("renorm", "Renormalized overlap matrix"),
41
+ ("ortho", "Orthonormalized overlap matrix")
42
+ ))
43
+
44
+ def __init__(self, overlap_data, calc_number=0, conf_thresh=1e-4, out_dir="./"):
45
+ try:
46
+ self.base_cmd = Config["wfoverlap"]["cmd"]
47
+ except KeyError:
48
+ self.log("WFOverlap cmd not found in ~/.pysisyphusrc!")
49
+ self.overlap_data = overlap_data
50
+ # Should correspond to the attribute of the parent calculator
51
+ self.calc_number = calc_number
52
+ self.conf_thresh = conf_thresh
53
+ self.out_dir = Path(out_dir).resolve()
54
+
55
+ with h5py.File(self.overlap_data, "r") as handle:
56
+ self.coords_list = handle["coords"][:]
57
+ self.mo_coeffs_list = handle["mo_coeffs"][:]
58
+ self.ci_coeffs_list = handle["ci_coeffs"][:]
59
+
60
+ self.mo_inds_list = list()
61
+ self.from_set_list = list()
62
+ self.to_set_list = list()
63
+ self.turbo_mos_list = list()
64
+
65
+ self.name = f"WFOWrapper2_{self.calc_number}"
66
+ self.occ_mo_num, self.virt_mo_num = self.ci_coeffs_list[0,0].shape
67
+ self.mo_num = self.occ_mo_num + self.virt_mo_num
68
+ self.base_det_str = "d"*self.occ_mo_num + "e"*self.virt_mo_num
69
+ self.fmt = "{: .10f}"
70
+
71
+ self.iter_counter = 0
72
+
73
+ self.set_data()
74
+
75
+ @property
76
+ def last_two_coords(self):
77
+ return self.coords_list[-2:]
78
+
79
+ def log(self, message):
80
+ self.logger.debug(f"{self.name}, " + message)
81
+
82
+ @staticmethod
83
+ def fake_turbo_mos(mo_coeffs):
84
+ """Create a mos file suitable for TURBOMOLE input. All MO eigenvalues
85
+ are set to 0.0. There is also a little deviation in the formatting
86
+ (see turbo_fmt()) but it works ..."""
87
+
88
+ def turbo_fmt(num):
89
+ """Not quite the real TURBOMOLE format, but it works ...
90
+ In TURBOMOLE the first character is always 0 for positive doubles
91
+ and - for negative doubles."""
92
+ return f"{num:+20.13E}".replace("E", "D")
93
+
94
+ base = "$scfmo scfconv=7 format(4d20.14)\n# from pysisyphus\n" \
95
+ "{mo_strings}\n$end"
96
+
97
+ # WFOverlap expects the string eigenvalue starting at 16, so we have
98
+ mo_str = "{mo_index:>6d} a eigenvalue=-.00000000000000D+00 " \
99
+ "nsaos={nsaos}\n{joined}"
100
+ nsaos = mo_coeffs.shape[0]
101
+
102
+ mo_strings = list()
103
+ for mo_index, mo in enumerate(mo_coeffs, 1):
104
+ in_turbo_fmt = [turbo_fmt(c) for c in mo]
105
+ # Combine into chunks of four
106
+ lines = ["".join(chnk) for chnk in chunks(in_turbo_fmt, 4)]
107
+ # Join the lines
108
+ joined = "\n".join(lines)
109
+ mo_strings.append(mo_str.format(mo_index=mo_index, nsaos=nsaos,
110
+ joined=joined))
111
+ return base.format(mo_strings="\n".join(mo_strings))
112
+
113
+ def ci_coeffs_above_thresh(self, ci_coeffs, thresh=1e-5):
114
+ mo_inds = np.where(np.abs(ci_coeffs) > thresh)
115
+ return mo_inds
116
+
117
+ def make_det_string(self, inds):
118
+ """Return spin adapted strings."""
119
+ from_mo, to_mo = inds
120
+ # Until now the first virtual MO (to_mo) has index 0. To subsitute
121
+ # the base_str at the correct index we have to increase all to_mo
122
+ # indices by the number off occupied MO.
123
+ to_mo += self.occ_mo_num
124
+ # Make string for excitation of an alpha electron
125
+ ab = list(self.base_det_str)
126
+ ab[from_mo] = "b"
127
+ ab[to_mo] = "a"
128
+ ab_str = "".join(ab)
129
+ # Make string for excitation of an beta electron
130
+ ba = list(self.base_det_str)
131
+ ba[from_mo] = "a"
132
+ ba[to_mo] = "b"
133
+ ba_str = "".join(ba)
134
+ return ab_str, ba_str
135
+
136
+ def generate_all_dets(self, occ_set1, virt_set1, occ_set2, virt_set2):
137
+ """Generate all possible single excitation determinant strings
138
+ from union(occ_mos) to union(virt_mos)."""
139
+ # Unite the respective sets of both calculations
140
+ occ_set = occ_set1 | occ_set2
141
+ virt_set = virt_set1 | virt_set2
142
+ # Genrate all possible excitations (combinations) from the occupied
143
+ # MO set to (and) the virtual MO set.
144
+ all_inds = [(om, vm) for om, vm
145
+ in itertools.product(occ_set, virt_set)]
146
+ det_strings = [self.make_det_string(inds) for inds in all_inds]
147
+ return all_inds, det_strings
148
+
149
+ def make_full_dets_list(self, all_inds, det_strings, ci_coeffs):
150
+ dets_list = list()
151
+ for inds, det_string in zip(all_inds, det_strings):
152
+ ab, ba = det_string
153
+ from_mo, to_mo = inds
154
+ per_state = ci_coeffs[:,from_mo,to_mo]
155
+ # Drop unimportant configurations, that are configurations
156
+ # having low weights in all states under consideration.
157
+ if np.sum(per_state**2) < self.conf_thresh:
158
+ continue
159
+ # A singlet determinant can be formed in two ways:
160
+ # (up down) (up down) (up down) ...
161
+ # or
162
+ # (down up) (down up) (down up) ...
163
+ # We take this into account by expanding the singlet determinants
164
+ # and using a proper normalization constant.
165
+ # See 10.1063/1.3000012 Eq. (5) and 10.1021/acs.jpclett.7b01479 SI
166
+ per_state *= 1/2**0.5
167
+ as_str = lambda arr: " ".join([self.fmt.format(cic)
168
+ for cic in arr])
169
+ ps_str = as_str(per_state)
170
+ mps_str = as_str(-per_state)
171
+ dets_list.append(f"{ab}\t{ps_str}")
172
+ dets_list.append(f"{ba}\t{mps_str}")
173
+ return dets_list
174
+
175
+ def set_from_nested_list(self, nested):
176
+ return set([i for i in itertools.chain(*nested)])
177
+
178
+ def set_data(self):
179
+ for ci_coeffs in self.ci_coeffs_list:
180
+ mo_inds = [self.ci_coeffs_above_thresh(state)
181
+ for state in ci_coeffs]
182
+ from_mos, to_mos = zip(*mo_inds)
183
+ from_set = self.set_from_nested_list(from_mos)
184
+ to_set = self.set_from_nested_list(to_mos)
185
+ mo_coeffs = self.mo_coeffs_list[self.iter_counter]
186
+ turbo_mos_fn = f"mos.{self.iter_counter}"
187
+ with open(turbo_mos_fn, "w") as handle:
188
+ handle.write(self.fake_turbo_mos(mo_coeffs))
189
+ self.turbo_mos_list.append(turbo_mos_fn)
190
+
191
+ self.mo_inds_list.append(mo_inds)
192
+ self.from_set_list.append(from_set)
193
+ self.to_set_list.append(to_set)
194
+ self.iter_counter += 1
195
+
196
+ def get_iteration(self, ind):
197
+ return (self.turbo_mos_list[ind], self.coords_list[ind],
198
+ self.ci_coeffs_list[ind], self.mo_inds_list[ind],
199
+ self.from_set_list[ind], self.to_set_list[ind])
200
+
201
+ def make_dets_header(self, cic, dets_list):
202
+ return f"{len(cic)} {self.mo_num} {len(dets_list)}"
203
+
204
+ def parse_wfoverlap_out(self, text, type_="ortho"):
205
+ """Returns overlap matrix."""
206
+ header_str = self.matrix_types[type_] + " <PsiA_i|PsiB_j>"
207
+ header = pp.Literal(header_str)
208
+ float_ = pp.Word(pp.nums+"-.")
209
+ psi_bra = pp.Literal("<Psi") + pp.Word(pp.alphas) \
210
+ + pp.Word(pp.nums) + pp.Literal("|")
211
+ psi_ket = pp.Literal("|Psi") + pp.Word(pp.alphas) \
212
+ + pp.Word(pp.nums) + pp.Literal(">")
213
+ matrix_line = pp.Suppress(psi_bra) + pp.OneOrMore(float_)
214
+
215
+ # I really don't know why this is needed but otherwise I can't parse
216
+ # overlap calculations with the true AO overlap matrix, even though
217
+ # the files appear completely similar regarding printing of the matrices.
218
+ # WTF. WTF!
219
+ text = text.replace("\n", " ")
220
+ parser = pp.SkipTo(header, include=True) \
221
+ + pp.OneOrMore(psi_ket) \
222
+ + pp.OneOrMore(matrix_line).setResultsName("overlap")
223
+
224
+ result = parser.parseString(text)
225
+
226
+ return np.array(list(result["overlap"]), dtype=np.float64)
227
+
228
+ def wf_overlap(self, ind1=-2, ind2=-1, ao_ovlp=None):
229
+ iter1 = self.get_iteration(ind1)
230
+ iter2 = self.get_iteration(ind2)
231
+
232
+ if ao_ovlp is None:
233
+ mo_coeffs_1 = self.mo_coeffs_list[ind1]
234
+ # mo_coeffs_2 = self.mo_coeffs_list[ind2]
235
+ mo_coeffs_1_inv = np.linalg.inv(mo_coeffs_1)
236
+ ao_ovlp = mo_coeffs_1_inv.dot(mo_coeffs_1_inv.T)
237
+
238
+ mos1, coords1, cic1, moi1, fs1, ts1 = iter1
239
+ mos2, coords2, cic2, moi2, fs2, ts2 = iter2
240
+ # Create a fake array for the ground state where all CI coefficients
241
+ # are zero and add it.
242
+ gs_cic = np.zeros_like(cic1[0])
243
+ cic1_with_gs = np.concatenate((gs_cic[None,:,:], cic1))
244
+ cic2_with_gs = np.concatenate((gs_cic[None,:,:], cic2))
245
+
246
+ all_inds, det_strings = self.generate_all_dets(fs1, ts1, fs2, ts2)
247
+ # Prepare line for ground state
248
+ gs_coeffs = np.zeros(len(cic1_with_gs))
249
+ # Ground state is 100% HF configuration
250
+ gs_coeffs[0] = 1
251
+ gs_coeffs_str = " ".join([self.fmt.format(c)
252
+ for c in gs_coeffs])
253
+ gs_line = f"{self.base_det_str}\t{gs_coeffs_str}"
254
+ dets1 = [gs_line] + self.make_full_dets_list(all_inds,
255
+ det_strings,
256
+ cic1_with_gs)
257
+ dets2 = [gs_line] + self.make_full_dets_list(all_inds,
258
+ det_strings,
259
+ cic2_with_gs)
260
+ header1 = self.make_dets_header(cic1_with_gs, dets1)
261
+ header2 = self.make_dets_header(cic2_with_gs, dets2)
262
+
263
+ backup_path = self.out_dir / f"wfo_{self.calc_number}.{ind1:03d}_{ind2:03d}"
264
+ with tempfile.TemporaryDirectory() as tmp_dir:
265
+ tmp_path = Path(tmp_dir)
266
+ self.log(f"Calculation in {tmp_dir}")
267
+ shutil.copy(mos1, tmp_path / "mos.1")
268
+ shutil.copy(mos2, tmp_path / "mos.2")
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_fn = "ciovl.in"
291
+ with open(tmp_path / ciovl_fn, "w") as handle:
292
+ handle.write(ciovl_in)
293
+
294
+ # Create a backup of the whole temporary directory
295
+ try:
296
+ shutil.rmtree(backup_path)
297
+ except FileNotFoundError:
298
+ pass
299
+ shutil.copytree(tmp_dir, backup_path)
300
+
301
+ cmd = f"{self.base_cmd} -m 4000 -f {ciovl_fn}".split()
302
+ result = subprocess.Popen(cmd, cwd=tmp_path,
303
+ stdout=subprocess.PIPE)
304
+ result.wait()
305
+ stdout = result.stdout.read().decode("utf-8")
306
+ if "differs significantly" in stdout:
307
+ self.log("WARNING: Orthogonalized matrix differs significantly "
308
+ "from original matrix! There is probably mixing with "
309
+ "external states.")
310
+
311
+ wfo_log_fn = self.out_dir / f"wfo_{self.calc_number}.{ind1:03d}_{ind2:03d}.out"
312
+ with open(wfo_log_fn, "w") as handle:
313
+ handle.write(stdout)
314
+ # Also copy the WFO-output to the input backup
315
+ shutil.copy(wfo_log_fn, backup_path)
316
+
317
+ matrices = [self.parse_wfoverlap_out(stdout, type_=key)
318
+ for key in self.matrix_types.keys()]
319
+
320
+ reshaped_mats = [mat.reshape(-1, len(cic2_with_gs))
321
+ for mat in matrices]
322
+ for key, mat in zip(self.matrix_types.keys(), reshaped_mats):
323
+ mat_fn = backup_path / f"{key}_mat.dat"
324
+ np.savetxt(mat_fn, mat)
325
+
326
+ # for mat in reshaped_mats:
327
+ # print(mat)
328
+ return reshaped_mats
329
+
330
+ def all_overlaps(self):
331
+ for i in range(self.iter_counter-1):
332
+ ind1 = i
333
+ ind2 = i+1
334
+ print(f"Doing overlaps between {ind1} and {ind2}")
335
+ overlap_mats = self.wf_overlap(ind1, ind2)
336
+ ovlp_mat_fn = f"wf_ovlp_mat_{ind1:03d}_{ind2:03d}.dat"
337
+ np.savetxt(ovlp_mat_fn, overlap_mats[-1])
338
+ print(f"Wrote '{ovlp_mat_fn}'")
339
+
340
+ def __str__(self):
341
+ return self.name