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,418 @@
1
+ from collections import namedtuple
2
+ import io
3
+ import json
4
+ import os
5
+ import re
6
+ import shutil
7
+ import textwrap
8
+
9
+ import numpy as np
10
+
11
+ from pysisyphus.calculators.Calculator import Calculator
12
+ from pysisyphus.calculators.parser import parse_turbo_gradient
13
+ from pysisyphus.calculators.ORCA import save_orca_pc_file
14
+ from pysisyphus.constants import BOHR2ANG, BOHRPERFS2AU
15
+ from pysisyphus.helpers import geom_loader
16
+ from pysisyphus.helpers_pure import file_or_str
17
+ from pysisyphus.xyzloader import make_xyz_str
18
+
19
+
20
+ OptResult = namedtuple("OptResult", "opt_geom opt_log")
21
+
22
+
23
+ class XTB(Calculator):
24
+
25
+ conf_key = "xtb"
26
+ _set_plans = (
27
+ "charges",
28
+ "json",
29
+ "xtbrestart",
30
+ )
31
+
32
+ def __init__(
33
+ self,
34
+ gbsa="",
35
+ alpb="",
36
+ gfn=2,
37
+ acc=1.0,
38
+ iterations=250,
39
+ etemp=None,
40
+ retry_etemp=None,
41
+ restart=False,
42
+ topo=None,
43
+ topo_update=None,
44
+ quiet=False,
45
+ **kwargs,
46
+ ):
47
+ """XTB calculator.
48
+
49
+ Wrapper for running energy, gradient and Hessian calculations by
50
+ XTB.
51
+
52
+ Parameters
53
+ ----------
54
+ gbsa : str, optional
55
+ Solvent for GBSA calculation, by default no solvent model is
56
+ used.
57
+ alpb : str, optional
58
+ Solvent for ALPB calculation, by default no solvent model is
59
+ used.
60
+ gfn : int or str, must be (0, 1, 2, or "ff")
61
+ Hamiltonian for the XTB calculation (GFN0, GFN1, GFN2, or GFNFF).
62
+ acc : float, optional
63
+ Accuracy control of the calculation, the lower the tighter several
64
+ numerical thresholds are chosen.
65
+ iterations : int, optional
66
+ The number of iterations in SCC calculation.
67
+ topo : str, optional
68
+ Path the a GFNFF-topolgy file. As setting up the topology may take
69
+ some time for sizable systems, it may be desired to reuse the file.
70
+ topo_update : int
71
+ Integer controlling the update interval of the GFNFF topology update.
72
+ If supplied, the topolgy will be recreated every N-th calculation.
73
+ mem : int
74
+ Mememory per core in MB.
75
+ quiet : bool, optional
76
+ Suppress creation of log files.
77
+ """
78
+ super().__init__(**kwargs)
79
+
80
+ self.gbsa = gbsa
81
+ self.alpb = alpb
82
+ self.gfn = gfn
83
+ self.acc = acc
84
+ self.iterations = iterations
85
+ self.etemp = etemp
86
+ self.retry_etemp = retry_etemp
87
+ self.restart = restart
88
+ if self.etemp is not None:
89
+ assert (
90
+ self.retry_etemp is None
91
+ ), "Using 'etemp' and 'retry_etemp' simultaneously is not possible!"
92
+ self.topo = topo
93
+ self.topo_update = topo_update
94
+ self.quiet = quiet
95
+
96
+ self.topo_used = 0
97
+ self.xtbrestart = None
98
+ valid_gfns = (0, 1, 2, "ff")
99
+ assert (
100
+ self.gfn in valid_gfns
101
+ ), f"Invalid gfn argument. Allowed arguments are: {', '.join(valid_gfns)}!"
102
+ self.uhf = self.mult - 1
103
+
104
+ self.inp_fn = "xtb.xyz"
105
+ self.out_fn = "xtb.out"
106
+ self.to_keep = (
107
+ "out:xtb.out",
108
+ "gradient",
109
+ "xtbopt.xyz",
110
+ "g98.out",
111
+ "xtb_trj.xyz",
112
+ # "json:xtbout.json",
113
+ "charges:charges",
114
+ "xcontrol",
115
+ )
116
+ if self.restart:
117
+ self.to_keep += ("xtbrestart", )
118
+ if self.quiet:
119
+ self.to_keep = ()
120
+
121
+ self.parser_funcs = {
122
+ "grad": self.parse_gradient,
123
+ "hess": self.parse_hessian,
124
+ "opt": self.parse_opt,
125
+ "md": self.parse_md,
126
+ "topo": self.parse_topo,
127
+ "noparse": lambda path: None,
128
+ "calc": self.parse_energy,
129
+ }
130
+
131
+ self.base_cmd = self.get_cmd()
132
+
133
+ def reattach(self, last_calc_cycle):
134
+ pass
135
+
136
+ def prepare_coords(self, atoms, coords):
137
+ coords = coords * BOHR2ANG
138
+ return make_xyz_str(atoms, coords.reshape((-1, 3)))
139
+
140
+ def prepare_input(self, atoms, coords, calc_type, point_charges=None):
141
+ path = self.prepare_path(use_in_run=True)
142
+
143
+ xcontrol_str = """
144
+ $write
145
+ json=true
146
+ $end
147
+ """
148
+
149
+ if point_charges is not None:
150
+ pc_fn = self.make_fn("pointcharges_inp.pc")
151
+ save_orca_pc_file(point_charges, pc_fn, hardness=99)
152
+ xcontrol_str += f"""
153
+ $embedding
154
+ input={pc_fn}
155
+ interface=orca
156
+ $end
157
+ """
158
+
159
+ xcontrol_str = textwrap.dedent(xcontrol_str.strip())
160
+ with open(path / "xcontrol", "w") as handle:
161
+ handle.write(xcontrol_str)
162
+
163
+ # Check if the topology has to be recreated/updated
164
+ if (
165
+ self.topo_used > 0
166
+ and self.topo_update
167
+ and (self.topo_used % self.topo_update == 0)
168
+ ):
169
+ results = self.run_topo(atoms, coords)
170
+ self.topo = results["topo"]
171
+ self.log(f"Updated topology! Saved to '{self.topo}'.")
172
+ if self.topo:
173
+ shutil.copy(self.topo, path / "gfnff_topo")
174
+ self.log(f"Using toplogy given in {self.topo}.")
175
+ self.topo_used += 1
176
+ if self.xtbrestart is not None:
177
+ shutil.copy(self.xtbrestart, path / "xtbrestart")
178
+ self.log(f"Using xtbrestart given in {self.xtbrestart}.")
179
+
180
+ def prepare_add_args(self, xcontrol=None):
181
+ add_args = (
182
+ f"--input xcontrol --chrg {self.charge} --uhf {self.uhf} "
183
+ f"--acc {self.acc} --iterations {self.iterations}".split()
184
+ )
185
+ if self.etemp:
186
+ etemp = f"--etemp {self.etemp}".split()
187
+ add_args = add_args + etemp
188
+
189
+ # Use solvent model if specified
190
+ if self.gbsa:
191
+ gbsa = f"--gbsa {self.gbsa}".split()
192
+ add_args = add_args + gbsa
193
+ elif self.alpb:
194
+ alpb = f"--alpb {self.alpb}".split()
195
+ add_args = add_args + alpb
196
+ # Select parametrization
197
+ gfn = ["--gfnff"] if self.gfn == "ff" else f"--gfn {self.gfn}".split()
198
+ add_args = add_args + gfn
199
+ return add_args
200
+
201
+ def get_pal_env(self):
202
+ env_copy = os.environ.copy()
203
+ env_copy["OMP_NUM_THREADS"] = str(self.pal)
204
+ env_copy["MKL_NUM_THREADS"] = str(self.pal)
205
+ # Per thread
206
+ env_copy["OMP_STACKSIZE"] = f"{self.mem}M"
207
+
208
+ return env_copy
209
+
210
+ def get_energy(self, atoms, coords, **prepare_kwargs):
211
+ results = self.get_forces(atoms, coords, **prepare_kwargs)
212
+ del results["forces"]
213
+ return results
214
+
215
+ def get_forces(self, atoms, coords, **prepare_kwargs):
216
+ self.prepare_input(atoms, coords, "forces", **prepare_kwargs)
217
+ inp = self.prepare_coords(atoms, coords)
218
+ add_args = self.prepare_add_args() + ["--grad"]
219
+ self.log(f"Executing {self.base_cmd} {add_args}")
220
+ kwargs = {
221
+ "calc": "grad",
222
+ "add_args": add_args,
223
+ "env": self.get_pal_env(),
224
+ }
225
+ results = self.run(inp, **kwargs)
226
+ return results
227
+
228
+ def get_hessian(self, atoms, coords, **prepare_kwargs):
229
+ self.prepare_input(atoms, coords, "hessian", **prepare_kwargs)
230
+ inp = self.prepare_coords(atoms, coords)
231
+ add_args = self.prepare_add_args() + ["--hess"]
232
+ self.log(f"Executing {self.base_cmd} {add_args}")
233
+ kwargs = {
234
+ "calc": "hess",
235
+ "add_args": add_args,
236
+ "env": self.get_pal_env(),
237
+ }
238
+ results = self.run(inp, **kwargs)
239
+ return results
240
+
241
+ def run_calculation(self, atoms, coords, **prepare_kwargs):
242
+ self.prepare_input(atoms, coords, "calculation", **prepare_kwargs)
243
+ inp = self.prepare_coords(atoms, coords)
244
+ kwargs = {
245
+ "calc": "calc",
246
+ "env": self.get_pal_env(),
247
+ }
248
+ energy = self.run(inp, **kwargs)
249
+ results = {"energy": energy}
250
+ return results
251
+
252
+ def run_topo(self, atoms, coords):
253
+ inp = self.prepare_coords(atoms, coords)
254
+ kwargs = {
255
+ "calc": "topo",
256
+ "cmd": [self.base_cmd, "topo"],
257
+ "env": self.get_pal_env(),
258
+ }
259
+ results = self.run(inp, **kwargs)
260
+ return results
261
+
262
+ def parse_topo(self, path):
263
+ fn = "gfnff_topo"
264
+ topo = path / fn
265
+ target = self.make_fn(fn)
266
+ shutil.copy(topo, target)
267
+
268
+ return {
269
+ "topo": target,
270
+ }
271
+
272
+ def get_mdrestart_str(self, coords, velocities):
273
+ """coords and velocities have to given in au!"""
274
+ vals = np.concatenate((coords, velocities), axis=1)
275
+
276
+ with io.StringIO() as io_stream:
277
+ np.savetxt(io_stream, vals, fmt="% .14e")
278
+ mdrestart = io_stream.getvalue()
279
+ # What does the -1.0 mean?
280
+ mdrestart = "-1.0\n" + mdrestart.replace("e", "D")
281
+ mdrestart = textwrap.indent(mdrestart, " ")
282
+ return mdrestart
283
+
284
+ def write_mdrestart(self, path, mdrestart_str):
285
+ with open(path / "mdrestart", "wb") as handle:
286
+ handle.write(mdrestart_str.encode("ascii"))
287
+
288
+ def run_md(self, atoms, coords, t, dt, velocities=None, dump=1):
289
+ """Expecting t and dt in fs, even though xtb wants t in ps!"""
290
+
291
+ restart = "false"
292
+ path = self.prepare_path(use_in_run=True)
293
+ if velocities is not None:
294
+ coords3d = coords.reshape(-1, 3)
295
+ velocities3d = velocities.reshape(-1, 3) * BOHRPERFS2AU
296
+ assert (
297
+ coords3d.shape == velocities3d.shape
298
+ ), "Shape of coordinates and velocities doesn't match!"
299
+ mdrestart_str = self.get_mdrestart_str(coords3d, velocities3d)
300
+ self.write_mdrestart(path, mdrestart_str)
301
+ restart = "true"
302
+ md_str = textwrap.dedent(
303
+ """
304
+ $md
305
+ hmass=1
306
+ dump={dump} # fs
307
+ nvt=false
308
+ restart={restart}
309
+ time={time} # ps
310
+ shake=0
311
+ step={step} # fs
312
+ velo=false
313
+ $end"""
314
+ )
315
+ t_ps = t / 1000
316
+ md_str_fmt = md_str.format(restart=restart, time=t_ps, step=dt, dump=dump)
317
+ with open(path / "xcontrol", "w") as handle:
318
+ handle.write(md_str_fmt)
319
+ inp = self.prepare_coords(atoms, coords)
320
+
321
+ add_args = self.prepare_add_args() + ["--input", "xcontrol", "--md"]
322
+ self.log(f"Executing {self.base_cmd} {add_args}")
323
+ kwargs = {
324
+ "calc": "md",
325
+ "add_args": add_args,
326
+ "env": self.get_pal_env(),
327
+ "keep": True,
328
+ }
329
+ geoms = self.run(inp, **kwargs)
330
+ return geoms
331
+
332
+ def parse_md(self, path):
333
+ assert (path / "xtbmdok").exists(), "File xtbmdok does not exist!"
334
+ geoms = geom_loader(path / "xtb_trj.xyz")
335
+ return geoms
336
+
337
+ def run_opt(self, atoms, coords, keep=True, keep_log=False):
338
+ inp = self.prepare_coords(atoms, coords)
339
+ add_args = self.prepare_add_args() + ["--opt", "tight"]
340
+ self.log(f"Executing {self.base_cmd} {add_args}")
341
+ kwargs = {
342
+ "calc": "opt",
343
+ "add_args": add_args,
344
+ "env": self.get_pal_env(),
345
+ "keep": keep,
346
+ "parser_kwargs": {"keep_log": keep_log},
347
+ }
348
+ opt_result = self.run(inp, **kwargs)
349
+ return opt_result
350
+
351
+ def parse_opt(self, path, keep_log=False):
352
+ xtbopt = path / "xtbopt.xyz"
353
+ if not xtbopt.exists():
354
+ self.log(f"{self.calc_number:03d} failed")
355
+ return None
356
+ opt_geom = geom_loader(xtbopt)
357
+ opt_geom.energy = self.parse_energy(path)
358
+
359
+ opt_log = None
360
+ if keep_log:
361
+ opt_log = geom_loader(path / "xtbopt.log")
362
+
363
+ opt_result = OptResult(opt_geom=opt_geom, opt_log=opt_log)
364
+ return opt_result
365
+
366
+ def parse_energy(self, path):
367
+ with open(path / self.out_fn) as handle:
368
+ text = handle.read()
369
+ energy_re = r"TOTAL ENERGY\s*([-\d\.]+) Eh"
370
+ energy = float(re.search(energy_re, text)[1])
371
+ return energy
372
+
373
+ def parse_gradient(self, path):
374
+ return parse_turbo_gradient(path)
375
+
376
+ def parse_hessian(self, path):
377
+ with open(path / "hessian") as handle:
378
+ text = handle.read()
379
+ hessian = np.array(text.split()[1:], dtype=float)
380
+ coord_num = int(hessian.size ** 0.5)
381
+ hessian = hessian.reshape(coord_num, coord_num)
382
+ energy = self.parse_energy(path)
383
+ results = {
384
+ "energy": energy,
385
+ "hessian": hessian,
386
+ }
387
+ return results
388
+
389
+ def parse_charges(self, fn=None):
390
+ if fn is None:
391
+ fn = self.charges
392
+ charges = np.loadtxt(fn, dtype=float)
393
+ return charges
394
+
395
+ def parse_charges_from_json(self, fn=None):
396
+ if fn is None:
397
+ fn = self.json
398
+ with open(fn, "r") as handle:
399
+ dump = json.load(handle)
400
+ charges = dump["partial charges"]
401
+ return charges
402
+
403
+ @staticmethod
404
+ @file_or_str(".out")
405
+ def check_termination(text):
406
+ term_re = re.compile("finished run on")
407
+ mobj = term_re.search(text)
408
+ return bool(mobj)
409
+
410
+ def get_retry_args(self):
411
+ if self.retry_etemp is None:
412
+ return []
413
+
414
+ self.log(f"Retrying calculation with increased etemp={self.retry_etemp}")
415
+ return f"--etemp {self.retry_etemp}".split()
416
+
417
+ def __str__(self):
418
+ return "XTB calculator"
@@ -0,0 +1,81 @@
1
+ import logging
2
+
3
+ __all__ = [
4
+ "AFIR",
5
+ "AtomAtomTransTorque",
6
+ "Composite",
7
+ "ConicalIntersection",
8
+ "DFTBp",
9
+ "DFTD4",
10
+ "Dimer",
11
+ "Dummy",
12
+ "EnergyMin",
13
+ "EGO",
14
+ "ExternalPotential",
15
+ "FakeASE",
16
+ "Gaussian09",
17
+ "Gaussian16",
18
+ "HardSphere",
19
+ "IPIServer",
20
+ "LennardJones",
21
+ "MOPAC",
22
+ "MultiCalc",
23
+ "OBabel",
24
+ "ONIOM",
25
+ "OpenMolcas",
26
+ "ORCA",
27
+ "ORCA5",
28
+ "Psi4",
29
+ "PyPsi4",
30
+ "PyXTB",
31
+ "Remote",
32
+ "TIP3P",
33
+ "Turbomole",
34
+ "TransTorque",
35
+ "XTB",
36
+ "CFOUR",
37
+ ]
38
+
39
+
40
+ from pysisyphus.calculators.AFIR import AFIR
41
+ from pysisyphus.calculators.AtomAtomTransTorque import AtomAtomTransTorque
42
+ from pysisyphus.calculators.Composite import Composite
43
+ from pysisyphus.calculators.ConicalIntersection import ConicalIntersection
44
+ from pysisyphus.calculators.DFTBp import DFTBp
45
+ from pysisyphus.calculators.DFTD4 import DFTD4
46
+ from pysisyphus.calculators.Dimer import Dimer
47
+ from pysisyphus.calculators.Dummy import Dummy
48
+ from pysisyphus.calculators.EnergyMin import EnergyMin
49
+ from pysisyphus.calculators.EGO import EGO
50
+ from pysisyphus.calculators.ExternalPotential import ExternalPotential
51
+ from pysisyphus.calculators.FakeASE import FakeASE
52
+ from pysisyphus.calculators.Gaussian09 import Gaussian09
53
+ from pysisyphus.calculators.Gaussian16 import Gaussian16
54
+ from pysisyphus.calculators.IPIServer import IPIServer
55
+ from pysisyphus.calculators.HardSphere import HardSphere, PWHardSphere
56
+ from pysisyphus.calculators.LennardJones import LennardJones
57
+ from pysisyphus.calculators.MultiCalc import MultiCalc
58
+ from pysisyphus.calculators.MOPAC import MOPAC
59
+ from pysisyphus.calculators.Psi4 import Psi4
60
+ from pysisyphus.calculators.OBabel import OBabel
61
+ from pysisyphus.calculators.ONIOMv2 import ONIOM
62
+ from pysisyphus.calculators.OpenMolcas import OpenMolcas
63
+ from pysisyphus.calculators.ORCA import ORCA
64
+ from pysisyphus.calculators.ORCA5 import ORCA5
65
+ from pysisyphus.calculators.PyPsi4 import PyPsi4
66
+ from pysisyphus.calculators.PyXTB import PyXTB
67
+ from pysisyphus.calculators.Remote import Remote
68
+ from pysisyphus.calculators.TIP3P import TIP3P
69
+ from pysisyphus.calculators.TransTorque import TransTorque
70
+ from pysisyphus.calculators.Turbomole import Turbomole
71
+ from pysisyphus.calculators.XTB import XTB
72
+ from pysisyphus.calculators.CFOUR import CFOUR
73
+
74
+
75
+ logger = logging.getLogger("dimer")
76
+ logger.setLevel(logging.DEBUG)
77
+ handler = logging.FileHandler("dimer.log", mode="w", delay=True)
78
+ fmt_str = "%(message)s"
79
+ formatter = logging.Formatter(fmt_str)
80
+ handler.setFormatter(formatter)
81
+ logger.addHandler(handler)
@@ -0,0 +1,139 @@
1
+ from dataclasses import dataclass
2
+ from enum import IntEnum
3
+
4
+
5
+ _JSON_DATA = {
6
+ # Generated from 'radii.cosmo'
7
+ #
8
+ # Version 1.0 080606
9
+ # entries per line:
10
+ # 1) symbol (two lower case characters)
11
+ # 2) radius in Angstroem (double)
12
+ # 3) quality of rad. (0|1|2) (integer) 0=some guess; 1=reasonable guess; 2=optimized
13
+ # 4) isodens in e/bohr**3 (double)
14
+ # For entry 2 and 4, -1.0 denotes an undefined value
15
+ "h": [1.3, 2, 0.0018],
16
+ "he": [1.638, 1, -1.0],
17
+ "li": [1.404, 1, -1.0],
18
+ "be": [1.053, 1, -1.0],
19
+ "b": [2.0475, 1, 0.001],
20
+ "c": [2.0, 2, 0.0016],
21
+ "n": [1.83, 2, 0.0017],
22
+ "o": [1.72, 2, 0.0013],
23
+ "f": [1.72, 2, 0.0011],
24
+ "ne": [1.8018, 1, -1.0],
25
+ "na": [1.755, 0, -1.0],
26
+ "mg": [1.638, 0, -1.0],
27
+ "al": [2.153, 1, 0.0035],
28
+ "si": [2.2, 1, 0.0013],
29
+ "p": [2.106, 1, 0.0016],
30
+ "s": [2.16, 2, 0.0009],
31
+ "cl": [2.05, 2, 0.0014],
32
+ "ar": [2.223, 0, -1.0],
33
+ "k": [2.223, 0, -1.0],
34
+ "ca": [2.223, 0, -1.0],
35
+ "sc": [2.223, 0, -1.0],
36
+ "ti": [2.223, 0, -1.0],
37
+ "v": [2.223, 0, -1.0],
38
+ "cr": [2.223, 0, -1.0],
39
+ "mn": [2.223, 0, -1.0],
40
+ "fe": [2.223, 0, -1.0],
41
+ "co": [2.223, 0, -1.0],
42
+ "ni": [2.223, 0, -1.0],
43
+ "cu": [2.223, 0, -1.0],
44
+ "zn": [1.626, 1, -1.0],
45
+ "ga": [2.223, 0, -1.0],
46
+ "ge": [2.7, 1, 0.001],
47
+ "as": [2.35, 1, 0.0011],
48
+ "se": [2.2, 1, 0.0013],
49
+ "br": [2.16, 2, 0.0012],
50
+ "kr": [2.223, 0, -1.0],
51
+ "rb": [2.223, 0, -1.0],
52
+ "sr": [2.223, 0, -1.0],
53
+ "y": [2.223, 0, -1.0],
54
+ "zr": [2.223, 0, -1.0],
55
+ "nb": [2.223, 0, -1.0],
56
+ "mo": [2.223, 0, -1.0],
57
+ "tc": [2.223, 0, -1.0],
58
+ "ru": [2.223, 0, -1.0],
59
+ "rh": [2.223, 0, -1.0],
60
+ "pd": [2.223, 0, -1.0],
61
+ "ag": [2.223, 0, -1.0],
62
+ "cd": [2.223, 0, -1.0],
63
+ "in": [2.223, 0, -1.0],
64
+ "sn": [2.55, 0, -1.0],
65
+ "sb": [2.223, 0, -1.0],
66
+ "te": [2.223, 0, -1.0],
67
+ "i": [2.32, 2, 0.0016],
68
+ "xe": [2.223, 0, -1.0],
69
+ "cs": [2.223, 0, -1.0],
70
+ "ba": [2.223, 0, -1.0],
71
+ "la": [2.223, 0, -1.0],
72
+ "ce": [2.223, 0, -1.0],
73
+ "pr": [2.223, 0, -1.0],
74
+ "nd": [2.223, 0, -1.0],
75
+ "pm": [2.223, 0, -1.0],
76
+ "sm": [2.223, 0, -1.0],
77
+ "eu": [2.223, 0, -1.0],
78
+ "gd": [2.223, 0, -1.0],
79
+ "tb": [2.223, 0, -1.0],
80
+ "dy": [2.223, 0, -1.0],
81
+ "ho": [2.223, 0, -1.0],
82
+ "er": [2.223, 0, -1.0],
83
+ "tm": [2.223, 0, -1.0],
84
+ "yb": [2.223, 0, -1.0],
85
+ "lu": [2.223, 0, -1.0],
86
+ "hf": [2.223, 0, -1.0],
87
+ "ta": [2.223, 0, -1.0],
88
+ "w": [2.223, 0, -1.0],
89
+ "re": [2.223, 0, -1.0],
90
+ "os": [2.223, 0, -1.0],
91
+ "ir": [2.223, 0, -1.0],
92
+ "pt": [2.223, 0, -1.0],
93
+ "au": [2.223, 0, -1.0],
94
+ "hg": [2.223, 0, -1.0],
95
+ "tl": [2.223, 0, -1.0],
96
+ "pb": [2.36, 1, -1.0],
97
+ "bi": [2.223, 0, -1.0],
98
+ "po": [2.223, 0, -1.0],
99
+ "at": [2.223, 0, -1.0],
100
+ "rn": [2.223, 0, -1.0],
101
+ "fr": [2.223, 0, -1.0],
102
+ "ra": [2.223, 0, -1.0],
103
+ "ac": [2.223, 0, -1.0],
104
+ "th": [2.223, 0, -1.0],
105
+ "pa": [2.223, 0, -1.0],
106
+ "u": [2.223, 0, -1.0],
107
+ "np": [2.223, 0, -1.0],
108
+ "pu": [2.223, 0, -1.0],
109
+ "q": [0.0, 0, -1.0],
110
+ }
111
+
112
+
113
+ class COSMORadiusQuality(IntEnum):
114
+ GUESS = 0
115
+ REASONABLE_GUESS = 1
116
+ OPTIMIZED = 2
117
+
118
+
119
+ cosmo_qualities ={
120
+ 0: COSMORadiusQuality["GUESS"],
121
+ 1: COSMORadiusQuality["REASONABLE_GUESS"],
122
+ 2: COSMORadiusQuality["OPTIMIZED"],
123
+ }
124
+
125
+
126
+ @dataclass
127
+ class COSMORadius:
128
+ atom: str
129
+ radius: float # in Angstrom
130
+ quality: COSMORadiusQuality
131
+ isodens: float # e/bohr³
132
+
133
+
134
+ COSMO_RADII = {
135
+ atom: COSMORadius(
136
+ atom=atom, radius=radius, quality=cosmo_qualities[quality], isodens=isodens
137
+ )
138
+ for atom, (radius, quality, isodens) in _JSON_DATA.items()
139
+ }