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,6 @@
1
+ from pysisyphus.calculators.ORCA import ORCA
2
+
3
+
4
+ class ORCA5(ORCA):
5
+
6
+ conf_key = "orca5"
@@ -0,0 +1,88 @@
1
+ import numpy as np
2
+
3
+ try:
4
+ from simtk.openmm import app
5
+ from simtk import openmm as mm
6
+ from simtk import unit
7
+ except ModuleNotFoundError:
8
+ print("OpenMM is not installed!")
9
+
10
+ from pysisyphus.constants import BOHR2ANG
11
+ from pysisyphus.calculators.Calculator import Calculator
12
+
13
+
14
+ class OpenMM(Calculator):
15
+ def __init__(self, topology, params, **kwargs):
16
+ super().__init__(**kwargs)
17
+
18
+ self.topology = topology
19
+ self.params = params
20
+ self.system = self.topology.createSystem(
21
+ self.params, nonbondedMethod=app.NoCutoff
22
+ )
23
+
24
+ dummy_int = mm.VerletIntegrator(0.001)
25
+ self.simulation = app.Simulation(self.topology, self.system, dummy_int)
26
+ self.context = self.simulation.context
27
+
28
+ self.en2au = 1 / unit.hartree / unit.AVOGADRO_CONSTANT_NA
29
+ self.frc2au = 1 / (unit.hartree / unit.bohr) / unit.AVOGADRO_CONSTANT_NA
30
+
31
+ def get_charges(self):
32
+ (nb_force,) = [
33
+ force
34
+ for force in self.system.getForces()
35
+ if force.__class__.__name__ == "NonbondedForce"
36
+ ]
37
+ charges = list()
38
+ for i in range(nb_force.getNumParticles()):
39
+ charge, *_ = nb_force.getParticleParameters(i)
40
+ charges.append(charge.value_in_unit(unit.elementary_charge))
41
+ charges = np.array(charges)
42
+ return charges
43
+
44
+ def report_charges(self):
45
+ """Total charge of the system.
46
+
47
+ Adapted from modeller.py _addIons() in OpenMM.
48
+ """
49
+
50
+ charges = self.get_charges()
51
+ total_charge = charges.sum()
52
+ charges_str = np.array2string(charges, precision=4)
53
+ self.log(f"OpenMM charges: {charges_str}")
54
+ self.log(f"OpenMM system total charge: {total_charge:.6f} e")
55
+
56
+ def get_dipole_moment(self, coords3d, reference=None, masses=None):
57
+ def get_com(coords3d):
58
+ total_mass = sum(masses)
59
+ com = (1 / total_mass * coords3d * masses[:, None]).sum(axis=0)
60
+ return com
61
+
62
+ charges = self.get_charges()
63
+ ref_dict = {
64
+ None: lambda c3d: c3d,
65
+ "centroid": lambda c3d: c3d.mean(axis=1)[None, :],
66
+ "com": lambda c3d: c3d - get_com(c3d)[None, :],
67
+ }
68
+ coords3d = ref_dict[reference](coords3d)
69
+ # Dipole moment vector in bohr * elementary_charge
70
+ dip_moms = (coords3d * charges[:, None]).sum(axis=0)
71
+ tot_dip_mom = np.linalg.norm(dip_moms)
72
+ return dip_moms, tot_dip_mom
73
+
74
+ def get_energy(self, atoms, coords, **prepare_kwargs):
75
+ results = self.get_forces(atoms, coords, **prepare_kwargs)
76
+ return {"energy": results["energy"]}
77
+
78
+ def get_forces(self, atoms, coords, **prepare_kwargs):
79
+ positions = coords.reshape(-1, 3) * BOHR2ANG / 10 # 2d array in nm
80
+ self.context.setPositions(positions)
81
+ state = self.context.getState(getEnergy=True, getForces=True)
82
+ energy = state.getPotentialEnergy() * self.en2au
83
+ forces = state.getForces(asNumpy=True)
84
+ forces = (forces * self.frc2au).reshape(-1)
85
+
86
+ energy = float(energy)
87
+ forces = np.array(forces)
88
+ return {"energy": energy, "forces": forces}
@@ -0,0 +1,281 @@
1
+ import os
2
+ from pathlib import Path
3
+ import re
4
+ import warnings
5
+
6
+ import numpy as np
7
+
8
+ from pysisyphus.calculators.Calculator import Calculator
9
+ from pysisyphus.constants import BOHR2ANG
10
+ from pysisyphus.xyzloader import make_xyz_str
11
+
12
+
13
+ class OpenMolcas(Calculator):
14
+
15
+ conf_key = "openmolcas"
16
+ _set_plans = (
17
+ ("rasorb", "inporb"),
18
+ "jobiph",
19
+ )
20
+
21
+ def __init__(
22
+ self,
23
+ basis,
24
+ inporb,
25
+ rasscf=None,
26
+ gateway=None,
27
+ mcpdft=None,
28
+ track=True,
29
+ **kwargs,
30
+ ):
31
+ super(OpenMolcas, self).__init__(**kwargs)
32
+
33
+ assert self.pal == 1, (
34
+ "RI SA-CASSCF analytical gradients do not work correctly in "
35
+ "parallel (yet). Consider using pal=1 instead of the current "
36
+ f"pal={self.pal}!"
37
+ )
38
+ env = os.environ
39
+ if not ("MOLCAS" in env):
40
+ warnings.warn(
41
+ "$MOLCAS environment variable is not set! Couldn't find it in the "
42
+ "environment!"
43
+ )
44
+
45
+ self.basis = basis
46
+ inporb = Path(inporb).absolute()
47
+ self.inporb = inporb
48
+ if rasscf is None:
49
+ rasscf = {}
50
+ self.rasscf = rasscf
51
+ if gateway is None:
52
+ gateway = {}
53
+ self.gateway = gateway
54
+ if mcpdft is None:
55
+ mcpdft = {}
56
+ self.mcpdft = mcpdft
57
+ self.track = track
58
+
59
+ self.to_keep = ("RasOrb", "out", "in", "JobIph", "rasscf.molden")
60
+ self.jobiph = ""
61
+
62
+ self.inp_fn = "openmolcas.in"
63
+ self.out_fn = "openmolcas.out"
64
+ self.float_regex = r"([\d\.\-E]+)"
65
+
66
+ self.openmolcas_input = """
67
+ >> copy {inporb} $Project.RasOrb
68
+ &gateway
69
+ coord
70
+ {xyz_str}
71
+ basis
72
+ {basis}
73
+ group
74
+ nosym
75
+ {gateway_kwargs}
76
+
77
+ &seward
78
+ doanalytical
79
+
80
+ &rasscf
81
+ charge
82
+ {charge}
83
+ spin
84
+ {mult}
85
+ fileorb
86
+ $Project.RasOrb
87
+ {rasscf_kwargs}
88
+
89
+ {mcpdft}
90
+
91
+ >> copy $Project.JobIph $CurrDir/$Project.JobIph
92
+
93
+ {rassi}
94
+
95
+ {alaska}
96
+ """
97
+
98
+ self.parser_funcs = {
99
+ "energy": self.parse_energy,
100
+ "grad": self.parse_gradient,
101
+ }
102
+
103
+ self.base_cmd = self.get_cmd()
104
+
105
+ def reattach(self, last_calc_cycle):
106
+ self.inporb = self.make_fn("RasOrb", last_calc_cycle)
107
+ self.jobiph = self.make_fn("JobIph", last_calc_cycle)
108
+ self.log(f"restarted. using {self.inporb}, {self.jobiph}")
109
+
110
+ def build_str_from_dict(self, dct):
111
+ strs = list()
112
+ for key, val in dct.items():
113
+ if val is None:
114
+ val = ""
115
+ strs.append(f"{key}\n{val}")
116
+ return "\n".join(strs)
117
+
118
+ def build_gateway_str(self):
119
+ return self.build_str_from_dict(self.gateway)
120
+
121
+ def build_rasscf_str(self):
122
+ return self.build_str_from_dict(self.rasscf)
123
+
124
+ def build_rassi_str(self):
125
+ # In the first iteration self.jobiph isn't set yet.
126
+ if (not self.track) or (self.calc_counter == 0):
127
+ return ""
128
+ else:
129
+ # JOB001 corresponds to the current iteration,
130
+ # JOB002 to the previous iteration.
131
+ return f"""
132
+ >> copy $Project.JobIph JOB001
133
+ >> copy {self.jobiph} JOB002
134
+ &rassi
135
+ track
136
+ """
137
+
138
+ def build_mcpdft_str(self):
139
+ if not self.mcpdft:
140
+ return ""
141
+
142
+ mcpdft_kwargs = self.build_str_from_dict(self.mcpdft)
143
+ return f"&mcpdft\n{mcpdft_kwargs}"
144
+
145
+ def get_pal_env(self):
146
+ env_copy = os.environ.copy()
147
+ env_copy["MOLCAS_NPROCS"] = str(self.pal)
148
+
149
+ return env_copy
150
+
151
+ def prepare_coords(self, atoms, coords):
152
+ coords = coords * BOHR2ANG
153
+ return make_xyz_str(atoms, coords.reshape((-1, 3)))
154
+
155
+ def prepare_input(self, atoms, coords, calc_type):
156
+ self.log(f"using inporb: {self.inporb}")
157
+ xyz_str = self.prepare_coords(atoms, coords)
158
+ alaska_str = "&alaska\npnew" if calc_type == "grad" else ""
159
+ inp = self.openmolcas_input.format(
160
+ inporb=self.inporb,
161
+ xyz_str=xyz_str,
162
+ basis=self.basis,
163
+ charge=self.charge,
164
+ mult=self.mult,
165
+ gateway_kwargs=self.build_gateway_str(),
166
+ rasscf_kwargs=self.build_rasscf_str(),
167
+ mcpdft=self.build_mcpdft_str(),
168
+ rassi=self.build_rassi_str(),
169
+ alaska=alaska_str,
170
+ )
171
+ return inp
172
+
173
+ def run_calculation(self, atoms, coords, calc_type="energy"):
174
+ inp = self.prepare_input(atoms, coords, calc_type)
175
+ add_args = ("-clean", "-oe", self.out_fn)
176
+ env_copy = self.get_pal_env()
177
+ env_copy["MOLCAS_PROJECT"] = f"{self.name}_{self.calc_counter}"
178
+ kwargs = {
179
+ "calc": calc_type,
180
+ "add_args": add_args,
181
+ "env": env_copy,
182
+ }
183
+ results = self.run(inp, **kwargs)
184
+ return results
185
+
186
+ def get_energy(self, atoms, coords):
187
+ return self.run_calculation(atoms, coords, "energy")
188
+
189
+ def get_forces(self, atoms, coords):
190
+ return self.run_calculation(atoms, coords, "grad")
191
+
192
+ def get_root(self):
193
+ ras = self.rasscf
194
+ return int(ras.get("mdrlxroot", ras.get("rlxroot", 1)))
195
+
196
+ def parse_energies(self, text):
197
+ if self.mcpdft:
198
+ root_re = r"PDFT Root\s*\d+\s*Total energy:\s*" + self.float_regex
199
+ matches = re.findall(root_re, text)
200
+ root_energies = np.array(matches, dtype=float)
201
+ root = self.get_root()
202
+ energy = root_energies[root - 1]
203
+ else:
204
+ # Energy of root for which gradient was computed
205
+ energy_regex = r"RASSCF state energy =\s*" + self.float_regex
206
+ energy = float(re.search(energy_regex, text).groups()[0])
207
+ # All state average energies
208
+ root_re = "RASSCF root number.+Total energy.+?" + self.float_regex
209
+ matches = re.findall(root_re, text)
210
+ root_energies = np.array(matches, dtype=float)
211
+ return energy, root_energies
212
+
213
+ def parse_energy(self, path):
214
+ with open(path / self.out_fn) as handle:
215
+ text = handle.read()
216
+ energy, _ = self.parse_energies(text)
217
+ return {
218
+ "energy": energy,
219
+ }
220
+
221
+ def parse_gradient(self, path):
222
+ results = {}
223
+ gradient_fn = os.path.join(path, self.out_fn)
224
+ with open(gradient_fn) as handle:
225
+ text = handle.read()
226
+
227
+ # Search for the block containing the gradient table
228
+ regex = r"Molecular gradients(.+?)--- Stop Module:\s*alaska"
229
+ floats = [self.float_regex for i in range(3)]
230
+ line_regex = r"([A-Z\d]+)\s*" + r"\s*".join(floats)
231
+
232
+ mobj = re.search(regex, text, re.DOTALL)
233
+ gradient = list()
234
+ for line in mobj.groups()[0].split("\n"):
235
+ # Now look for the lines containing the gradient
236
+ mobj = re.match(line_regex, line.strip())
237
+ if not mobj:
238
+ continue
239
+ # Discard first column (atom+number)
240
+ gradient.append(mobj.groups()[1:])
241
+ gradient = np.array(gradient, dtype=float).flatten()
242
+
243
+ if self.track and self.calc_counter > 0:
244
+ self.parse_rassi_track(path)
245
+
246
+ energy, _ = self.parse_energies(text)
247
+
248
+ results["energy"] = energy
249
+ # results["sa_energies"] = sa_energies
250
+ results["forces"] = -gradient
251
+
252
+ return results
253
+
254
+ def parse_rassi_track(self, path):
255
+ gradient_fn = path / self.out_fn
256
+ with open(gradient_fn) as handle:
257
+ text = handle.read()
258
+ track_re = (
259
+ r"Initial root:\s*(\d+)\s*Overlaps with current "
260
+ r"states:(.+)New root:\s*(\d+)"
261
+ )
262
+ # overlap_re = "OVERLAP MATRIX FOR THE ORIGINAL STATES:(.+?)##"
263
+ mobj = re.search(track_re, text, re.DOTALL)
264
+
265
+ initial_root, overlaps, new_root = mobj.groups()
266
+ overlaps = np.array(overlaps.strip().split(), dtype=float).reshape(-1, 2)
267
+ # Filters for overlaps > 10% (0.1**2 ~ 0.31622)
268
+ thresh = 0.1
269
+ inds = np.where(np.abs(overlaps[:, 1]) > thresh**0.5)
270
+ ov_perc_str = ", ".join([f"{nr:.0f}: {ov**2:.2%}" for nr, ov in overlaps[inds]])
271
+ self.log(
272
+ f"Overlaps between previous root {initial_root} and "
273
+ f"new roots bigger {thresh:.0%}: {ov_perc_str}. Will "
274
+ f"use root {new_root} for the following gradient calculation."
275
+ )
276
+ if new_root != initial_root:
277
+ self.log("Found a root flip!")
278
+ self.mdrlxroot = new_root
279
+
280
+ def __str__(self):
281
+ return "OpenMolcas calculator"