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,159 @@
1
+ # [1] https://doi.org/10.1063/1.4937410
2
+ # The consequences of improperly describing oscillator strengths
3
+ # beyond the electric dipole approximation
4
+ # Lestrange, Egidi, Li, 2015
5
+ # [2] https://doi.org/10.1016/0009-2614(95)01036-9
6
+ # Ab initio calculation and display of the rotary strength tensor in
7
+ # the random phase approximation. Method and model studies.
8
+ # Pedersen, Hansen, 1995
9
+
10
+ from typing import List, Optional
11
+
12
+ import numpy as np
13
+ from numpy.typing import NDArray
14
+
15
+
16
+ def get_multipole_moment(
17
+ order: int,
18
+ coords3d: NDArray[float],
19
+ origin: NDArray[float],
20
+ multipole_ints: NDArray[float],
21
+ nuc_charges: NDArray[int],
22
+ P: NDArray[float],
23
+ ) -> NDArray[float]:
24
+ """
25
+ order
26
+ Kind of requested multipoles: (1, dipole moment), (2, quadrupole moment).
27
+ coords3d
28
+ Cartesian coordinates of shape (natoms, 3).
29
+ origin
30
+ Origin of the multipole expansion. The supplied integrales must
31
+ be calculated w.r.t. this origin.
32
+ multipole_ints
33
+ Linear or quadratic multipole moment integrals.
34
+ nuc_charges
35
+ Nuclear charges.
36
+ P
37
+ Density matrix in the AO basis.
38
+ """
39
+ origin = np.array(origin, dtype=float)
40
+ assert origin.size == 3
41
+ assert len(coords3d) == len(nuc_charges)
42
+
43
+ # Make a copy, as the coordinates must be give w.r.t. the origin, which
44
+ # may be != (0., 0., 0.).
45
+ coords3d = coords3d.copy()
46
+ coords3d -= origin[None, :]
47
+
48
+ electronic = np.einsum("...ij,ji->...", multipole_ints, P)
49
+ if order == 1:
50
+ nuclear = np.einsum("i,ix->x", nuc_charges, coords3d)
51
+ elif order == 2:
52
+ nuclear = np.einsum("i,ix,iy->xy", nuc_charges, coords3d, coords3d)
53
+ else:
54
+ raise Exception(f"Multipoles of order={order} are not implemented!")
55
+ moment = nuclear - electronic
56
+ return moment
57
+
58
+
59
+ def get_transition_multipole_moment(
60
+ multipole_ints: NDArray[float],
61
+ C_a: NDArray[float],
62
+ C_b: NDArray[float],
63
+ T_a: NDArray[float],
64
+ T_b: NDArray[float] = None,
65
+ occ_a: Optional[int] = None,
66
+ occ_b: Optional[int] = None,
67
+ full: bool = False,
68
+ ) -> List[NDArray[float]]:
69
+ """
70
+ Transition multipole moments from transition density matrices.
71
+
72
+ This functions relies on the following normalization
73
+
74
+ closed shell: 0.5 = norm(X_a)**2 - norm(Y_a)**2
75
+ open shell: 1.0 = norm(X_a,X_b)**2 - norm(Y_a,Y_b)**2
76
+
77
+ with X_a,X_b indicating a vector formed by concatenating the elements
78
+ of X_a and X_b for every state. See also Eq. (33) in [1].
79
+
80
+ Parameters
81
+ ----------
82
+ multipole_integrals
83
+ Multipole integrals in the AO basis of the desired ordered,
84
+ e.g., linear moment for transition dipole moments or quadratic
85
+ moments for quadrupole transition moments.
86
+ C_a
87
+ MO-coefficients for α-electrons.
88
+ C_b
89
+ MO-coefficients for β-electrons.
90
+ T_a
91
+ Numpy array containing transition density matrices of shape
92
+ (nstates, occ, virt) or (occ, virt) in the α-electron space.
93
+ The transition density must be given in the MO-basis!
94
+ T_b
95
+ See P_a. Optional. If not provided, P_b is derived from P_a.
96
+ occ_a
97
+ Number of α-electrons.
98
+ occ_b
99
+ Number of β-electrons.
100
+ full
101
+ Use all MOs to transform multipole integrals. Needed for state-to-state
102
+ transition denstiy matrices of shape (occ+virt, occ+virt).
103
+
104
+ Returns
105
+ -------
106
+ trans_moments
107
+ Transition moments of the respective order for all provided
108
+ states.
109
+ """
110
+
111
+ # Deal with unrestricted transition density matrices that contain
112
+ # only one state.
113
+ def atleast_3d(tden):
114
+ if tden.ndim == 2:
115
+ tden = tden[None, :]
116
+ return tden
117
+
118
+ T_a = atleast_3d(T_a)
119
+ if T_b is not None:
120
+ T_b = atleast_3d(T_b)
121
+ # Expected shape: (nstates, occ, virt)
122
+ assert T_a.ndim == 3
123
+ if not full:
124
+ assert occ_a is not None
125
+
126
+ def get_trans_moment(
127
+ C: NDArray[float], occ: int, T: NDArray[float]
128
+ ) -> NDArray[float]:
129
+ # Transform AO integrals to MO basis.
130
+ # Excited state to excited state transition densities will span all
131
+ # molecular orbitals.
132
+ if full:
133
+ C_occ = C
134
+ C_virt = C
135
+ # Ground state to excited state transition density matrices will be
136
+ # of shape (occ, virt).
137
+ else:
138
+ C_occ = C[:, :occ]
139
+ C_virt = C[:, occ:]
140
+ multipole_ints_mo = np.einsum(
141
+ "jl,...lm,mk->...jk", C_occ.T, multipole_ints, C_virt, optimize="greedy",
142
+ )
143
+
144
+ """
145
+ Then contract with multipole integrals. For TDMs see Eq. (18) in [2].
146
+ i : Excited state number
147
+ j : occ. MO space
148
+ k : virt. MO space
149
+ """
150
+ trans_moment = np.einsum("...jk,ijk->i...", multipole_ints_mo, T, optimize="greedy")
151
+ return trans_moment
152
+
153
+ # Transitions between α -> α and β -> β
154
+ trans_moment = get_trans_moment(C_a, occ_a, T_a)
155
+ if T_b is None:
156
+ trans_moment *= 2
157
+ else:
158
+ trans_moment += get_trans_moment(C_b, occ_b, T_b)
159
+ return trans_moment
@@ -0,0 +1,36 @@
1
+ from math import prod
2
+
3
+ import numpy as np
4
+ from numpy.typing import NDArray
5
+ from scipy.special import factorial2
6
+
7
+ from pysisyphus.wavefunction.helpers import canonical_order
8
+
9
+
10
+ # @functools.cache
11
+ def get_lmn_factors(L: int):
12
+ lmns = canonical_order(L)
13
+ lmn_factors = np.zeros(len(lmns))
14
+ for i, lmn in enumerate(lmns):
15
+ lmn_factors[i] = prod([factorial2(2 * am - 1) for am in lmn])
16
+ lmn_factors = 1 / np.sqrt(lmn_factors)
17
+ return lmn_factors
18
+
19
+
20
+ def norm_cgto_lmn(coeffs: NDArray[float], exps: NDArray[float], L: int):
21
+ N = 0.0
22
+ for i, expi in enumerate(exps):
23
+ for j, expj in enumerate(exps):
24
+ tmp = coeffs[i] * coeffs[j] / (expi + expj) ** (L + 1.5)
25
+ tmp *= np.sqrt(expi * expj) ** (L + 1.5)
26
+ N += tmp
27
+ N = np.sqrt(exps ** (L + 1.5) / (np.pi**1.5 / 2**L * N))
28
+ # Or w/ array broadccasting
29
+ # N = coeffs[None, :] * coeffs[:, None] / (exps[None, :] + exps[:, None]) ** (L + 1.5)
30
+ # N = (N * np.sqrt((exps[None, :] * exps[:, None]) ** (L + 1.5))).sum()
31
+ # N = np.sqrt(exps ** (L + 1.5) / (np.pi**1.5 / 2**L * N))
32
+
33
+ mod_coeffs = N * coeffs
34
+ lmn_factors = get_lmn_factors(L)
35
+
36
+ return mod_coeffs, lmn_factors
@@ -0,0 +1,134 @@
1
+ from dataclasses import dataclass
2
+ from typing import List, Tuple
3
+
4
+ import numpy as np
5
+ from numpy.typing import NDArray
6
+ import scipy as sp
7
+
8
+ from pysisyphus.wavefunction.helpers import symmetric_orthogonalization
9
+ from pysisyphus.wavefunction import Wavefunction
10
+
11
+
12
+ @dataclass
13
+ class PopAnalysis:
14
+ # atoms: List[str]
15
+ # coords3d: NDArray[float]
16
+ pop_a: NDArray[float]
17
+ pop_b: NDArray[float]
18
+ nuc_charges: NDArray[float]
19
+
20
+ @property
21
+ def charges(self):
22
+ return self.nuc_charges - self.pop_a - self.pop_b
23
+
24
+ @property
25
+ def tot_charge(self):
26
+ return self.charges.sum()
27
+
28
+ @property
29
+ def spin_pop(self):
30
+ return np.abs(self.pop_a - self.pop_b)
31
+
32
+ @property
33
+ def alpha_spin_pop(self):
34
+ spin_pop = self.pop_a - self.pop_b
35
+ beta_mask = spin_pop < 0.0
36
+ spin_pop[beta_mask] = 0.0
37
+ return spin_pop
38
+
39
+ @property
40
+ def beta_spin_pop(self):
41
+ spin_pop = self.pop_a - self.pop_b
42
+ alpha_mask = spin_pop > 0.0
43
+ spin_pop[alpha_mask] = 0.0
44
+ return np.abs(spin_pop)
45
+
46
+
47
+ def mulliken_charges(
48
+ P: Tuple[NDArray[float]],
49
+ S: NDArray[float],
50
+ nuc_charges: NDArray[int],
51
+ ao_centers: List[int],
52
+ ) -> PopAnalysis:
53
+ def mulliken_atom_pops(P: NDArray[float], S: NDArray[float]) -> NDArray[float]:
54
+ ao_populations = np.einsum("ij,ji->i", P, S)
55
+ atom_populations = np.zeros(len(nuc_charges))
56
+ for i, center in enumerate(ao_centers):
57
+ atom_populations[center] += ao_populations[i]
58
+ return atom_populations
59
+
60
+ atom_populations_a = mulliken_atom_pops(P[0], S)
61
+ atom_populations_b = mulliken_atom_pops(P[1], S)
62
+
63
+ pop_ana = PopAnalysis(
64
+ pop_a=atom_populations_a,
65
+ pop_b=atom_populations_b,
66
+ nuc_charges=nuc_charges,
67
+ )
68
+ return pop_ana
69
+
70
+
71
+ def mulliken_charges_from_wf(wf: Wavefunction) -> NDArray[float]:
72
+ return mulliken_charges(
73
+ P=wf.P,
74
+ S=wf.S,
75
+ nuc_charges=wf.nuc_charges,
76
+ ao_centers=wf.ao_centers,
77
+ )
78
+
79
+
80
+ def make_iaos(
81
+ C_occ: NDArray[float],
82
+ S_org: NDArray[float],
83
+ S_minao: NDArray[float],
84
+ S_cross: NDArray[float],
85
+ ) -> NDArray[float]:
86
+ """Intrinsic atomic orbitals.
87
+
88
+ [1] https://doi.org/10.1021/ct400687b
89
+ """
90
+ P12 = sp.linalg.solve(S_org, S_cross) # Projector on basis1, S1⁻¹ S12
91
+ P21 = sp.linalg.solve(S_minao, S_cross.T) # Projector on basis2, S2⁻¹ S21
92
+
93
+ # Depolarized MOs in basis2
94
+ C2_depol = P12.dot(P21).dot(C_occ)
95
+ C2_depol = symmetric_orthogonalization(C2_depol, S_org)
96
+
97
+ O = C_occ.dot(C_occ.T).dot(S_org)
98
+ O_ = C2_depol.dot(C2_depol.T).dot(S_org)
99
+ iaos = (2 * O.dot(O_) - O_ - O).dot(P12) + P12
100
+ iaos = symmetric_orthogonalization(iaos, S_org)
101
+
102
+ return iaos
103
+
104
+
105
+ def iao_charges_from_wf(wf: Wavefunction) -> PopAnalysis:
106
+ """IAO charges.
107
+
108
+ Extension to ES is described here:
109
+ https://chemistry.stackexchange.com/a/75913
110
+ """
111
+ S_org = wf.S
112
+ C_occ = wf.C_occ
113
+ minao_shells = wf.shells.from_basis("minao")
114
+ S_minao = getattr(minao_shells, "S_cart" if wf.is_cartesian else "S_sph")
115
+ S_cross = wf.S_with_shells(
116
+ minao_shells
117
+ ) # Overlap between original and MINAO basis
118
+
119
+ def get_iao_P(C_occ: NDArray[float]):
120
+ iaos = make_iaos(C_occ, S_org, S_minao, S_cross)
121
+ C_iao = iaos.T @ S_org @ C_occ # Projection of original MOs onto IAOs
122
+ P_iao = C_iao @ C_iao.T
123
+ return P_iao
124
+
125
+ # Always assume separate α C_occ and β C_occ matrices.
126
+ P_iao = np.array([get_iao_P(c_occ) for c_occ in C_occ])
127
+
128
+ minao_ao_centers = list(minao_shells.sph_ao_centers)
129
+ return mulliken_charges(
130
+ P=P_iao,
131
+ S=np.eye(len(minao_ao_centers)),
132
+ nuc_charges=wf.nuc_charges,
133
+ ao_centers=minao_ao_centers,
134
+ )