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,139 @@
1
+ import numpy as np
2
+ from sympy import symbols, exp
3
+
4
+ # [1] 10.1142/9789812839664_0016
5
+ # G. Henkelman, G. Jóhannesson, and H. Jónsson
6
+ # Theoretical Methods in Condensed Phase Chemistry
7
+ # (Springer, Netherlands, 2002), pp. 287
8
+ # [2] https://aip.scitation.org/doi/pdf/10.1063/1.480097?class=pdf
9
+ # I'm very sure that Fig. 6 and Fig. 5 are not the potentials that are
10
+ # described in the paper. There are two errors in the paper. A_1 is
11
+ # actually -1.5 and not 1.5 and s_x_2 is 0.5 and not 5.0. You also
12
+ # have to divide by (2*s_x_i**2) and not only by (2*s_x_i) as given
13
+ # in Eq. (22).
14
+
15
+ class LEPSExpr:
16
+
17
+
18
+ def __init__(self):
19
+ """Generates sympy expression for various LEPS potentials."""
20
+ # V_harmonic uses b = 0.80
21
+ self.abc = (0.05, 0.30, 0.05)
22
+ self.ds = (4.746, 4.746, 3.445)
23
+ self.r0 = 0.742
24
+ self.alpha = 1.942
25
+
26
+ # Used for LEPS + harmonic oscillator
27
+ self.rac = 3.742
28
+ self.kc = 0.2025
29
+ self.c_ = 1.154
30
+
31
+ self.choices = {
32
+ "leps": self.get_leps,
33
+ "harmonic": self.get_harmonic,
34
+ "tot": self.get_tot,
35
+ "dimer": self.get_dimer,
36
+ }
37
+
38
+ def get_leps(self):
39
+ V_expr = self.V_LEPS()
40
+ xlim = (0, 6)
41
+ ylim = (0, 12)
42
+ levels = np.linspace(-5, 5, 250)
43
+ return V_expr, xlim, ylim, levels
44
+
45
+ def get_harmonic(self):
46
+ V_expr = self.V_harmonic()
47
+ levels = np.linspace(-20, 20, 250)
48
+ xlim = (0.4, 3.2)
49
+ ylim = (-2, 2)
50
+ return V_expr, xlim, ylim, levels
51
+
52
+ def get_tot(self):
53
+ V_expr = self.V_tot()
54
+ levels = np.linspace(-5, 2, 75)
55
+ xlim = (0.4, 3.2)
56
+ ylim = (-2, 2)
57
+ return V_expr, xlim, ylim, levels
58
+
59
+ def get_dimer(self):
60
+ V_expr = self.V_dimer()
61
+ levels = None
62
+ xlim = (0.25, 3.25)
63
+ ylim = (-3.5, 3.5)
64
+ return V_expr, xlim, ylim, levels
65
+
66
+ def get_expr(self, pot_type="leps"):
67
+ assert pot_type in self.choices
68
+ return self.choices[pot_type]()
69
+
70
+
71
+ def Q(self, d, alpha, r0, r):
72
+ """Coulomb interactions."""
73
+ return d/2* (3/2*exp(-2*alpha*(r-r0)) - exp(-alpha*(r-r0)))
74
+
75
+ def J(self, d, alpha, r0, r):
76
+ """Quantum mechanical exchange interaction."""
77
+ return d/4 * (exp(-2*alpha*(r-r0))-6*exp(-alpha*(r-r0)))
78
+
79
+ def G(self, a, b):
80
+ "Gaussian function."""
81
+ return exp(-0.5*((a/0.1)**2 +(b/0.35)**2))
82
+
83
+ def Gdimer(self, x, y, A, x0, y0, sx, sy):
84
+ return A * exp(-(x-x0)**2/(2*sx**2)) * exp(-(y-y0)**2/(2*sy**2))
85
+
86
+ def V_LEPS(self, x=None, y=None, abc=None):
87
+ """Equation (A.1) in [1].
88
+ Mimics reaction involving three atoms confined to motion along
89
+ a line."""
90
+ if abc is None:
91
+ abc = self.abc
92
+ a, b, c = abc
93
+ if x is None:
94
+ x = symbols("x")
95
+ if y is None:
96
+ y = symbols("y")
97
+ rs = (x, y, self.rac)
98
+
99
+ Qab, Qbc, Qac = [self.Q(d, self.alpha, self.r0, r)
100
+ for d, r in zip(self.ds, rs)]
101
+ Jab, Jbc, Jac = [self.J(d, self.alpha, self.r0, r)
102
+ for d, r in zip(self.ds, rs)]
103
+
104
+ first_term = Qab/(1+a) + Qbc/(1+b) + Qac/(1+c)
105
+ second_term = Jab**2/(1+a)**2 + Jbc**2/(1+b)**2 + Jac**2/(1+c)**2
106
+ third_term = (-Jab*Jbc / ((1+a)*(1+b))
107
+ -Jbc*Jac / ((1+b)*(1+c))
108
+ -Jab*Jac / ((1+a)*(1+c))
109
+ )
110
+ return first_term - (second_term + third_term)**0.5
111
+
112
+ def V_harmonic(self):
113
+ """Equation (A.2) in [1].
114
+ A and C are fixed, only B can move. A condensed phase environment
115
+ is represented by adding a harmonic oscillator degree of freedom."""
116
+ x, y = symbols("x y")
117
+ abc = (0.05, 0.80, 0.05)
118
+ return (self.V_LEPS(x, self.rac-x, abc)
119
+ + 2*self.kc*(x-(self.rac/2 - y/self.c_))**2
120
+ )
121
+
122
+ def V_tot(self):
123
+ """Equation (A.3) in [1].
124
+ Additional saddle point."""
125
+ x, y = symbols("x y")
126
+ return self.V_harmonic() + 1.5 * self.G(x-2.02083, y+0.272881)
127
+
128
+ def V_dimer(self):
129
+ """III. Results Section A in [3]. Two additional saddle points
130
+ from two added gaussians."""
131
+ x, y = symbols("x y")
132
+ # Ai , x0i , y0i , sxi, syi
133
+ params = ((-1.5, 2.02083, -0.172881, 0.1, 0.35),
134
+ ( 6.0, 0.8 , 2.0 , 0.5, 0.7 ))
135
+ G0, G1 = [self.Gdimer(x, y, *parms) for parms in params]
136
+ return self.V_harmonic() + G0 + G1
137
+
138
+ def __str__(self):
139
+ return "LEPSExpr"
@@ -0,0 +1,80 @@
1
+ import numpy as np
2
+
3
+ from pysisyphus.calculators.Calculator import Calculator
4
+
5
+
6
+ class LennardJones(Calculator):
7
+
8
+ # Corresponds to σ = 1 Å, as the default value in ASE, but
9
+ # pysisyphus uses au/Bohr.
10
+ def __init__(self, sigma=1.8897261251, epsilon=1, rc=None):
11
+ super().__init__()
12
+
13
+ self.sigma = sigma
14
+ self.epsilon = epsilon
15
+ # Cutoff distance
16
+ if rc is None:
17
+ rc = 3 * self.sigma
18
+ self.rc = rc
19
+ # Shift energy
20
+ self.e0 = (4 * self.epsilon *
21
+ ((self.sigma/self.rc)**12 - (self.sigma/self.rc)**6)
22
+ )
23
+
24
+ def calculate(self, coords3d):
25
+ # Index pairs
26
+ a, b = np.triu_indices(len(coords3d), 1)
27
+
28
+ # Distances
29
+ diffs = coords3d[a] - coords3d[b] # Shape: (N_atoms, 3)
30
+ rs = np.linalg.norm(diffs, axis=1)
31
+ c6 = np.where(rs <= self.rc, (self.sigma/rs)**6, np.zeros_like(rs))
32
+ energy = -self.e0 * (c6 != 0.0).sum()
33
+ c12 = c6**2
34
+ energy += np.sum(4*self.epsilon * (c12 - c6))
35
+
36
+ """
37
+ Gradient related remarks:
38
+
39
+ Lennard-Jones-potential:
40
+ LJ(r) =
41
+ 4*ε*[(σ/r)**12 - (σ/r)**6]
42
+
43
+ Derivative of quotient appearing in LJ potential w.r.t first cartesian
44
+ coordinate:
45
+ d(σ/r)**n/dx_1
46
+ = σ**n * d/dx_1 r**(-n)
47
+ = σ**n * (-n/2) * (2x1-2x2) * r**(-n) * r**(-2)
48
+ = σ**n * r**(-n) * (-n) * (x1-x2) * r**(-2)
49
+ = (σ/r)**n * (-n) * (x1-x2) / r**2
50
+
51
+ Derivate w.r.t to cartesian x coordinate of atom A (x_1):
52
+ dLJ(r)/dx_1 =
53
+ 24*ε*[-2*(σ/r)**12 + (σ/r)**6]*(x1-x2)/r**2
54
+
55
+ Derivate w.r.t to cartesian x coordinate of atom B (x_2):
56
+ dLJ(r)/dx_2 =
57
+ -24*ε*[-2*(σ/r)**12 + (σ/r)**6]*(x1-x2)/r**2
58
+
59
+ The derivate w.r.t to x_2 differs only by a factor of -1!
60
+ """
61
+ prefactors = 24*self.epsilon * (c6 - 2*c12) / rs**2
62
+ products = prefactors[:,None] * diffs
63
+
64
+ gradient = np.zeros_like(coords3d)
65
+ # Every pair (a, b) contributes to the total gradient of atoms a and b.
66
+ for i, prod in enumerate(products):
67
+ gradient[a[i]] += prod
68
+ gradient[b[i]] -= prod
69
+
70
+ return energy, -gradient
71
+
72
+ def get_energy(self, atoms, coords):
73
+ energy, _ = self.calculate(coords.reshape(-1, 3))
74
+ return {"energy": energy}
75
+
76
+ def get_forces(self, atoms, coords):
77
+ energy, forces = self.calculate(coords.reshape(-1, 3))
78
+ return {"energy": energy,
79
+ "forces": forces.flatten(),
80
+ }
@@ -0,0 +1,219 @@
1
+ import re
2
+ import textwrap
3
+
4
+ import numpy as np
5
+
6
+ from pysisyphus.constants import BOHR2ANG, AU2KCALPERMOL
7
+ from pysisyphus.calculators.Calculator import Calculator
8
+ from pysisyphus.helpers_pure import file_or_str
9
+
10
+
11
+ class MOPAC(Calculator):
12
+ """http://openmopac.net/manual/"""
13
+
14
+ conf_key = "mopac"
15
+
16
+ MULT_STRS = {
17
+ 1: "SINGLET",
18
+ 2: "DOUBLET",
19
+ 3: "TRIPLET",
20
+ 4: "QUARTET",
21
+ 5: "QUINTET",
22
+ 6: "SEXTET",
23
+ 7: "SEPTET",
24
+ 8: "OCTET",
25
+ }
26
+
27
+ CALC_TYPES = {
28
+ "energy": "1SCF",
29
+ "gradient": "1SCF GRADIENTS",
30
+ "hessian": "DFORCE FORCE LET",
31
+ }
32
+
33
+ METHODS = [
34
+ m.lower()
35
+ for m in "AM1 PM3 PM6 PM6-DH2 PM6-D3 PM6-DH+ PM6-DH2 PM6-DH2X " # lgtm [py/non-iterable-in-for-loop]
36
+ "PM6-D3H4 PM6-D3H4X PM7 PM7-TS".split()
37
+ ]
38
+
39
+ def __init__(self, method="PM7", **kwargs):
40
+ super().__init__(**kwargs)
41
+
42
+ self.method = method
43
+ assert (
44
+ self.method.lower() in self.METHODS
45
+ ), f"Invalid method={self.method}! Supported methods are ({self.METHODS})"
46
+
47
+ self.uhf = "UHF" if self.mult != 1 else ""
48
+
49
+ _ = "mopac"
50
+ self.inp_fn = f"{_}.mop"
51
+ self.out_fn = f"{_}.out"
52
+ self.aux_fn = f"{_}.aux"
53
+ self.to_keep = ("mop", "out", "arc", "aux")
54
+
55
+ self.parser_funcs = {
56
+ "energy": self.parse_energy,
57
+ "grad": self.parse_grad,
58
+ "hessian": self.parse_hessian,
59
+ }
60
+
61
+ self.base_cmd = self.get_cmd()
62
+
63
+ """
64
+ 1SCF: Do only SCF
65
+ AUX: Creates a checkpoint file
66
+ NOREO: Dont reorient geometry
67
+ """
68
+
69
+ self.inp = textwrap.dedent(
70
+ """
71
+ NOSYM {method} {mult} CHARGE={charge} {calc_type} {uhf} THREADS={pal} AUX(6,PRECISION=9) NOREOR
72
+
73
+
74
+ {coord_str}
75
+ """
76
+ ).strip()
77
+
78
+ self.log(f"Created MOPAC calculator using the '{self.method}' method.")
79
+
80
+ def prepare_coords(self, atoms, coords, opt=False):
81
+ coords = coords.reshape(-1, 3) * BOHR2ANG
82
+ # Optimization flag for coordinate
83
+ of = 1 if opt else 0
84
+ coord_str = "\n".join(
85
+ [
86
+ f"{a} {c[0]: 10.08f} {of} {c[1]: 10.08f} {of} {c[2]: 10.08f} {of}"
87
+ for a, c in zip(atoms, coords)
88
+ ]
89
+ )
90
+ return coord_str
91
+
92
+ def prepare_input(self, atoms, coords, calc_type, opt=False):
93
+ coord_str = self.prepare_coords(atoms, coords, opt)
94
+
95
+ inp = self.inp.format(
96
+ method=self.method,
97
+ charge=self.charge,
98
+ mult=self.MULT_STRS[self.mult],
99
+ uhf=self.uhf,
100
+ calc_type=self.CALC_TYPES[calc_type],
101
+ coord_str=coord_str,
102
+ pal=self.pal,
103
+ # mem=self.mem,
104
+ )
105
+ return inp
106
+
107
+ def get_energy(self, atoms, coords, **prepare_kwargs):
108
+ calc_type = "energy"
109
+ inp = self.prepare_input(atoms, coords, calc_type)
110
+ # with open("inp.mop", "w") as handle:
111
+ # handle.write(inp)
112
+ # import sys; sys.exit()
113
+ results = self.run(inp, calc="energy")
114
+ return results
115
+
116
+ def get_forces(self, atoms, coords, **prepare_kwargs):
117
+ calc_type = "gradient"
118
+ inp = self.prepare_input(atoms, coords, calc_type, opt=True)
119
+ results = self.run(inp, calc="grad")
120
+ return results
121
+
122
+ def get_hessian(self, atoms, coords, **prepare_kwargs):
123
+ calc_type = "hessian"
124
+ inp = self.prepare_input(atoms, coords, calc_type, opt=True)
125
+ results = self.run(inp, calc="hessian")
126
+ return results
127
+
128
+ def run_calculation(self, atoms, coords, **prepare_kwargs):
129
+ return self.get_energy(atoms, coords, **prepare_kwargs)
130
+
131
+ def read_aux(self, path):
132
+ with open(path / self.aux_fn) as handle:
133
+ text = handle.read()
134
+ return text
135
+
136
+ def parse_energy(self, path):
137
+ return self.parse_energy_from_aux(self.read_aux(path))
138
+
139
+ @staticmethod
140
+ @file_or_str(".aux", method=False)
141
+ def parse_energy_from_aux(text):
142
+ energy_re = r"HEAT_OF_FORMATION:KCAL/MOL=([\d\-D+\.]+)"
143
+ mobj = re.search(energy_re, text)
144
+ energy = float(mobj[1].replace("D", "E")) / AU2KCALPERMOL
145
+
146
+ result = {
147
+ "energy": energy,
148
+ }
149
+ return result
150
+
151
+ def parse_grad(self, path):
152
+ text = self.read_aux(path)
153
+ # grad_re = "GRADIENTS:KCAL.+$\s+(.+)$"
154
+ # mobj = re.search(grad_re, text, re.MULTILINE)
155
+ grad_re = r"GRADIENTS:KCAL/MOL/ANGSTROM\[\d+]=\s+(.+)\s+OVERLAP_MATRIX"
156
+ mobj = re.search(grad_re, text, re.DOTALL)
157
+ # Gradients are given in kcal*mol/angstrom
158
+ gradients = np.array(mobj[1].split(), dtype=float)
159
+ # Convert to hartree/bohr
160
+ gradients = gradients / AU2KCALPERMOL / BOHR2ANG
161
+
162
+ forces = -gradients
163
+ result = {
164
+ "forces": forces,
165
+ }
166
+ result.update(self.parse_energy(path))
167
+ return result
168
+
169
+ def parse_hessian(self, path):
170
+ return self.parse_hessian_from_aux(self.read_aux(path))
171
+
172
+ @staticmethod
173
+ @file_or_str(".aux", method=False)
174
+ def parse_hessian_from_aux(text):
175
+ # Parse employed masses, as the given hessian is mass-weighted
176
+ # and we have to un-weigh it.
177
+ mass_re = re.compile(
178
+ r"ISOTOPIC_MASSES\[(\d+)\]=\s*(.+?)ROTAT_CONSTS", re.DOTALL
179
+ )
180
+ # mobj = re.search(mass_re, text, re.MULTILINE)
181
+ mass_mobj = mass_re.search(text)
182
+ masses = np.array(mass_mobj[2].strip().split(), dtype=float)
183
+ # This matrix is used to un-weigh the hessian
184
+ M = np.diag(np.sqrt(np.repeat(masses, 3)))
185
+ # For N atoms we expect 3N cartesian coordinates
186
+ coord_num = masses.size * 3
187
+
188
+ hess_re = r" # Lower half triangle only\s+([\s\.\-\d]+)\s+NORMAL_MODE"
189
+ tril_hess = re.search(hess_re, text)[1].strip().split()
190
+ tril_hess = np.array(tril_hess, dtype=float)
191
+ assert tril_hess.size == sum(range(coord_num + 1))
192
+ hessian_m = np.zeros((coord_num, coord_num))
193
+ tril_indices = np.tril_indices(coord_num)
194
+ hessian_m[tril_indices] = tril_hess
195
+
196
+ triu_indices = np.triu_indices(coord_num, k=1)
197
+ hessian_m[triu_indices] = hessian_m.T[triu_indices]
198
+
199
+ # Hessian is given in mdyn/(Å*amu).
200
+ # In a first step we have to unweigh the hessian using the matrix
201
+ # built from the parsed masses.
202
+ hessian = M @ hessian_m @ M
203
+ # Then we have to convert mdyn/Å to Hartree/Bohr²
204
+ # mdyn/Å = 100 kg/s²
205
+ # Hartree/Bohr² ~ 1556.8931 kg/s²
206
+ #
207
+ # 1 mydn/Å * (100 / 1556.8931 Hartree/Bohr² * Å/mydn) = 0.06423 Hartree/Bohr²
208
+ hessian *= 0.06423
209
+
210
+ energy = MOPAC.parse_energy_from_aux(text)["energy"]
211
+
212
+ result = {
213
+ "energy": energy,
214
+ "hessian": hessian,
215
+ }
216
+ return result
217
+
218
+ def __str__(self):
219
+ return f"MOPAC({self.name})"
@@ -0,0 +1,51 @@
1
+ # [1] http://www.cims.nyu.edu/~eve2/string_jcp_simplified07.pdf
2
+
3
+ import numpy as np
4
+
5
+ from pysisyphus.calculators.AnaPotBase import AnaPotBase
6
+
7
+
8
+ class MullerBrownPot(AnaPotBase):
9
+ def __init__(self):
10
+ A = (-200, -100, -170, 15)
11
+ x0 = (1.0, 0.0, -0.5, -1.0)
12
+ y0 = (0.0, 0.5, 1.5, 1.0)
13
+ a = (-1.0, -1.0, -6.5, 0.7)
14
+ b = (0.0, 0.0, 11.0, 0.6)
15
+ c = (-10.0, -10.0, -6.5, 0.7)
16
+
17
+ # V_str_base = """{Ai} * exp(
18
+ # {ai}*(x-{xi})**2
19
+ # + {bi}*(x-{xi})*(y-{yi})
20
+ # + {ci}*(y-{yi})**2
21
+ # )"""
22
+ V_str_base = (
23
+ "{Ai}*exp({ai}*(x-{xi})**2 + {bi}*(x-{xi})*(y-{yi}) + {ci}*(y-{yi})**2)"
24
+ )
25
+ V_str = ""
26
+ V_strs = [
27
+ V_str_base.format(Ai=A[i], ai=a[i], xi=x0[i], bi=b[i], yi=y0[i], ci=c[i])
28
+ for i in range(4)
29
+ ]
30
+ V_str = " + ".join(V_strs)
31
+ xlim = (-1.75, 1.25)
32
+ ylim = (-0.5, 2.25)
33
+ levels = np.linspace(-200, 100, 100)
34
+ minima = (
35
+ (-0.5582236, 1.441725842, 0.0),
36
+ (0.62349941, 0.028037758, 0.0),
37
+ (-0.0435, 0.4648, 0.0),
38
+ )
39
+ saddles = ((-0.822, 0.624, 0.0),)
40
+
41
+ super(MullerBrownPot, self).__init__(
42
+ V_str=V_str,
43
+ xlim=xlim,
44
+ ylim=ylim,
45
+ levels=levels,
46
+ minima=minima,
47
+ saddles=saddles,
48
+ )
49
+
50
+ def __str__(self):
51
+ return "MullerBrownPot calculator"
@@ -0,0 +1,85 @@
1
+ import sys
2
+ import time
3
+
4
+ from pysisyphus.calculators.Calculator import Calculator
5
+ from pysisyphus.calculators import ORCA, ORCA5, Turbomole, XTB
6
+
7
+ CALC_CLASSES = {
8
+ "orca": ORCA.ORCA,
9
+ "orca5": ORCA5.ORCA5,
10
+ "turbomole": Turbomole.Turbomole,
11
+ "xtb": XTB.XTB,
12
+ }
13
+
14
+ try:
15
+ from pysisyphus.calculators import PySCF
16
+
17
+ CALC_CLASSES["pyscf"] = PySCF.PySCF
18
+ except ModuleNotFoundError:
19
+ pass
20
+
21
+
22
+ def calcs_from_dict(calc_dict, base_name, calc_number, charge, mult, pal, mem):
23
+ keys_calcs = {}
24
+ calc_kwargs_ = {
25
+ "calc_number": calc_number,
26
+ "charge": charge,
27
+ "mult": mult,
28
+ "pal": pal,
29
+ "mem": mem,
30
+ }
31
+ # Try to distinguish the calculators according to their base_name. If no
32
+ # base_name is given we rely on the calc_number.
33
+ base_name = base_name if base_name != "" else f"{calc_number:03d}"
34
+ for i, (key, kwargs) in enumerate(calc_dict.items()):
35
+ calc_kwargs = calc_kwargs_.copy()
36
+ calc_kwargs["base_name"] = f"{base_name}_{key}"
37
+ # Don't modify original dict
38
+ kwargs = kwargs.copy()
39
+ type_ = kwargs.pop("type")
40
+ calc_kwargs.update(**kwargs)
41
+ calc_cls = CALC_CLASSES[type_]
42
+ keys_calcs[key] = calc_cls(**calc_kwargs)
43
+ return keys_calcs
44
+
45
+
46
+ class MultiCalc(Calculator):
47
+ def __init__(self, calcs, **kwargs):
48
+ super().__init__(**kwargs)
49
+
50
+ self.do_hess = {
51
+ key: calc_dict.pop("do_hess", False) for key, calc_dict in calcs.items()
52
+ }
53
+ self.keys_calcs = calcs_from_dict(
54
+ calcs,
55
+ self.base_name,
56
+ self.calc_number,
57
+ self.charge,
58
+ self.mult,
59
+ self.pal,
60
+ self.mem,
61
+ )
62
+ max_len = max([len(key) for key in self.keys_calcs.keys()])
63
+ self.max_fmt = f" >{max_len+2}"
64
+
65
+ def run_calculation(self, atoms, coords, **prepare_kwargs):
66
+ all_results = {}
67
+ for name, calc in self.keys_calcs.items():
68
+ if self.do_hess[name]:
69
+ run_func = calc.get_hessian
70
+ else:
71
+ run_func = calc.run_calculation
72
+ key = f"{self.base_name}_{name}"
73
+ print(f"Running {name:{self.max_fmt}} ... ", end="")
74
+ try:
75
+ start = time.time()
76
+ results = run_func(atoms, coords, **prepare_kwargs)
77
+ end = time.time()
78
+ duration = end - start
79
+ print(f"took {duration:.0f} s.")
80
+ except Exception as err:
81
+ print("\nCalculation failed!")
82
+ print(err)
83
+ sys.stdout.flush()
84
+ all_results[key] = results
85
+ return all_results
@@ -0,0 +1,45 @@
1
+ # [1] https://doi.org/10.1016/j.cplett.2004.07.079
2
+ # The reaction pathway of a potential energy surface as curve
3
+ # with induced tangent
4
+ # Hirsch, Quapp, 2004
5
+
6
+
7
+ import numpy as np
8
+
9
+ from pysisyphus.calculators.AnaPotBase import AnaPotBase
10
+
11
+
12
+ class NFK(AnaPotBase):
13
+ def __init__(self, C=0.06, **kwargs):
14
+ """NFK surface of Hirsch and Quapp.
15
+
16
+ See Fig. 4 in [1] and the appendix.
17
+ """
18
+
19
+ # Note that C is substituted in
20
+ V_str = f"{C} * (x**2 + y**2)**2 + x*y - 9*exp(-(x-3)**2-y**2) - 9*exp(-(x+3)**2 - y**2)"
21
+ kwargs_ = {
22
+ "V_str": V_str,
23
+ "xlim": (-3, 3),
24
+ "ylim": (-3, 3),
25
+ "levels": np.linspace(-7, 3.5, 70),
26
+ "minima": ((2.71268103, -0.15093971, 0.0), (-2.7126810, 0.1509397, 0.0)),
27
+ "saddles": ((0.0, 0.0, 0.0),),
28
+ }
29
+ kwargs_.update(kwargs)
30
+ super().__init__(**kwargs_)
31
+
32
+ def __str__(self):
33
+ return "NFK calculator"
34
+
35
+
36
+ class ModNFK(NFK):
37
+ def __init__(self, C=0.03, **kwargs):
38
+ kwargs["minima"] = (
39
+ (-2.84721930, 0.15702574, 0.0),
40
+ (2.84721930, -0.15702574, 0.0),
41
+ )
42
+ super().__init__(C, **kwargs)
43
+
44
+ def __str__(self):
45
+ return "ModNFK calculator"