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.
- hessian_ff/__init__.py +50 -0
- hessian_ff/analytical_hessian.py +609 -0
- hessian_ff/constants.py +46 -0
- hessian_ff/forcefield.py +339 -0
- hessian_ff/loaders.py +608 -0
- hessian_ff/native/Makefile +8 -0
- hessian_ff/native/__init__.py +28 -0
- hessian_ff/native/analytical_hessian.py +88 -0
- hessian_ff/native/analytical_hessian_ext.cpp +258 -0
- hessian_ff/native/bonded.py +82 -0
- hessian_ff/native/bonded_ext.cpp +640 -0
- hessian_ff/native/loader.py +349 -0
- hessian_ff/native/nonbonded.py +118 -0
- hessian_ff/native/nonbonded_ext.cpp +1150 -0
- hessian_ff/prmtop_parmed.py +23 -0
- hessian_ff/system.py +107 -0
- hessian_ff/terms/__init__.py +14 -0
- hessian_ff/terms/angle.py +73 -0
- hessian_ff/terms/bond.py +44 -0
- hessian_ff/terms/cmap.py +406 -0
- hessian_ff/terms/dihedral.py +141 -0
- hessian_ff/terms/nonbonded.py +209 -0
- hessian_ff/tests/__init__.py +0 -0
- hessian_ff/tests/conftest.py +75 -0
- hessian_ff/tests/data/small/complex.parm7 +1346 -0
- hessian_ff/tests/data/small/complex.pdb +125 -0
- hessian_ff/tests/data/small/complex.rst7 +63 -0
- hessian_ff/tests/test_coords_input.py +44 -0
- hessian_ff/tests/test_energy_force.py +49 -0
- hessian_ff/tests/test_hessian.py +137 -0
- hessian_ff/tests/test_smoke.py +18 -0
- hessian_ff/tests/test_validation.py +40 -0
- hessian_ff/workflows.py +889 -0
- mlmm/__init__.py +36 -0
- mlmm/__main__.py +7 -0
- mlmm/_version.py +34 -0
- mlmm/add_elem_info.py +374 -0
- mlmm/advanced_help.py +91 -0
- mlmm/align_freeze_atoms.py +601 -0
- mlmm/all.py +3535 -0
- mlmm/bond_changes.py +231 -0
- mlmm/bool_compat.py +223 -0
- mlmm/cli.py +574 -0
- mlmm/cli_utils.py +166 -0
- mlmm/default_group.py +337 -0
- mlmm/defaults.py +467 -0
- mlmm/define_layer.py +526 -0
- mlmm/dft.py +1041 -0
- mlmm/energy_diagram.py +253 -0
- mlmm/extract.py +2213 -0
- mlmm/fix_altloc.py +464 -0
- mlmm/freq.py +1406 -0
- mlmm/harmonic_constraints.py +140 -0
- mlmm/hessian_cache.py +44 -0
- mlmm/hessian_calc.py +174 -0
- mlmm/irc.py +638 -0
- mlmm/mlmm_calc.py +2262 -0
- mlmm/mm_parm.py +945 -0
- mlmm/oniom_export.py +1983 -0
- mlmm/oniom_import.py +457 -0
- mlmm/opt.py +1742 -0
- mlmm/path_opt.py +1353 -0
- mlmm/path_search.py +2299 -0
- mlmm/preflight.py +88 -0
- mlmm/py.typed +1 -0
- mlmm/pysis_runner.py +45 -0
- mlmm/scan.py +1047 -0
- mlmm/scan2d.py +1226 -0
- mlmm/scan3d.py +1265 -0
- mlmm/scan_common.py +184 -0
- mlmm/summary_log.py +736 -0
- mlmm/trj2fig.py +448 -0
- mlmm/tsopt.py +2871 -0
- mlmm/utils.py +2309 -0
- mlmm/xtb_embedcharge_correction.py +475 -0
- mlmm_toolkit-0.2.2.dev0.dist-info/METADATA +1159 -0
- mlmm_toolkit-0.2.2.dev0.dist-info/RECORD +372 -0
- mlmm_toolkit-0.2.2.dev0.dist-info/WHEEL +5 -0
- mlmm_toolkit-0.2.2.dev0.dist-info/entry_points.txt +2 -0
- mlmm_toolkit-0.2.2.dev0.dist-info/licenses/LICENSE +674 -0
- mlmm_toolkit-0.2.2.dev0.dist-info/top_level.txt +4 -0
- pysisyphus/Geometry.py +1667 -0
- pysisyphus/LICENSE +674 -0
- pysisyphus/TableFormatter.py +63 -0
- pysisyphus/TablePrinter.py +74 -0
- pysisyphus/__init__.py +12 -0
- pysisyphus/calculators/AFIR.py +452 -0
- pysisyphus/calculators/AnaPot.py +20 -0
- pysisyphus/calculators/AnaPot2.py +48 -0
- pysisyphus/calculators/AnaPot3.py +12 -0
- pysisyphus/calculators/AnaPot4.py +20 -0
- pysisyphus/calculators/AnaPotBase.py +337 -0
- pysisyphus/calculators/AnaPotCBM.py +25 -0
- pysisyphus/calculators/AtomAtomTransTorque.py +154 -0
- pysisyphus/calculators/CFOUR.py +250 -0
- pysisyphus/calculators/Calculator.py +844 -0
- pysisyphus/calculators/CerjanMiller.py +24 -0
- pysisyphus/calculators/Composite.py +123 -0
- pysisyphus/calculators/ConicalIntersection.py +171 -0
- pysisyphus/calculators/DFTBp.py +430 -0
- pysisyphus/calculators/DFTD3.py +66 -0
- pysisyphus/calculators/DFTD4.py +84 -0
- pysisyphus/calculators/Dalton.py +61 -0
- pysisyphus/calculators/Dimer.py +681 -0
- pysisyphus/calculators/Dummy.py +20 -0
- pysisyphus/calculators/EGO.py +76 -0
- pysisyphus/calculators/EnergyMin.py +224 -0
- pysisyphus/calculators/ExternalPotential.py +264 -0
- pysisyphus/calculators/FakeASE.py +35 -0
- pysisyphus/calculators/FourWellAnaPot.py +28 -0
- pysisyphus/calculators/FreeEndNEBPot.py +39 -0
- pysisyphus/calculators/Gaussian09.py +18 -0
- pysisyphus/calculators/Gaussian16.py +726 -0
- pysisyphus/calculators/HardSphere.py +159 -0
- pysisyphus/calculators/IDPPCalculator.py +49 -0
- pysisyphus/calculators/IPIClient.py +133 -0
- pysisyphus/calculators/IPIServer.py +234 -0
- pysisyphus/calculators/LEPSBase.py +24 -0
- pysisyphus/calculators/LEPSExpr.py +139 -0
- pysisyphus/calculators/LennardJones.py +80 -0
- pysisyphus/calculators/MOPAC.py +219 -0
- pysisyphus/calculators/MullerBrownSympyPot.py +51 -0
- pysisyphus/calculators/MultiCalc.py +85 -0
- pysisyphus/calculators/NFK.py +45 -0
- pysisyphus/calculators/OBabel.py +87 -0
- pysisyphus/calculators/ONIOMv2.py +1129 -0
- pysisyphus/calculators/ORCA.py +893 -0
- pysisyphus/calculators/ORCA5.py +6 -0
- pysisyphus/calculators/OpenMM.py +88 -0
- pysisyphus/calculators/OpenMolcas.py +281 -0
- pysisyphus/calculators/OverlapCalculator.py +908 -0
- pysisyphus/calculators/Psi4.py +218 -0
- pysisyphus/calculators/PyPsi4.py +37 -0
- pysisyphus/calculators/PySCF.py +341 -0
- pysisyphus/calculators/PyXTB.py +73 -0
- pysisyphus/calculators/QCEngine.py +106 -0
- pysisyphus/calculators/Rastrigin.py +22 -0
- pysisyphus/calculators/Remote.py +76 -0
- pysisyphus/calculators/Rosenbrock.py +15 -0
- pysisyphus/calculators/SocketCalc.py +97 -0
- pysisyphus/calculators/TIP3P.py +111 -0
- pysisyphus/calculators/TransTorque.py +161 -0
- pysisyphus/calculators/Turbomole.py +965 -0
- pysisyphus/calculators/VRIPot.py +37 -0
- pysisyphus/calculators/WFOWrapper.py +333 -0
- pysisyphus/calculators/WFOWrapper2.py +341 -0
- pysisyphus/calculators/XTB.py +418 -0
- pysisyphus/calculators/__init__.py +81 -0
- pysisyphus/calculators/cosmo_data.py +139 -0
- pysisyphus/calculators/parser.py +150 -0
- pysisyphus/color.py +19 -0
- pysisyphus/config.py +133 -0
- pysisyphus/constants.py +65 -0
- pysisyphus/cos/AdaptiveNEB.py +230 -0
- pysisyphus/cos/ChainOfStates.py +725 -0
- pysisyphus/cos/FreeEndNEB.py +25 -0
- pysisyphus/cos/FreezingString.py +103 -0
- pysisyphus/cos/GrowingChainOfStates.py +71 -0
- pysisyphus/cos/GrowingNT.py +309 -0
- pysisyphus/cos/GrowingString.py +508 -0
- pysisyphus/cos/NEB.py +189 -0
- pysisyphus/cos/SimpleZTS.py +64 -0
- pysisyphus/cos/__init__.py +22 -0
- pysisyphus/cos/stiffness.py +199 -0
- pysisyphus/drivers/__init__.py +17 -0
- pysisyphus/drivers/afir.py +855 -0
- pysisyphus/drivers/barriers.py +271 -0
- pysisyphus/drivers/birkholz.py +138 -0
- pysisyphus/drivers/cluster.py +318 -0
- pysisyphus/drivers/diabatization.py +133 -0
- pysisyphus/drivers/merge.py +368 -0
- pysisyphus/drivers/merge_mol2.py +322 -0
- pysisyphus/drivers/opt.py +375 -0
- pysisyphus/drivers/perf.py +91 -0
- pysisyphus/drivers/pka.py +52 -0
- pysisyphus/drivers/precon_pos_rot.py +669 -0
- pysisyphus/drivers/rates.py +480 -0
- pysisyphus/drivers/replace.py +219 -0
- pysisyphus/drivers/scan.py +212 -0
- pysisyphus/drivers/spectrum.py +166 -0
- pysisyphus/drivers/thermo.py +31 -0
- pysisyphus/dynamics/Gaussian.py +103 -0
- pysisyphus/dynamics/__init__.py +20 -0
- pysisyphus/dynamics/colvars.py +136 -0
- pysisyphus/dynamics/driver.py +297 -0
- pysisyphus/dynamics/helpers.py +256 -0
- pysisyphus/dynamics/lincs.py +105 -0
- pysisyphus/dynamics/mdp.py +364 -0
- pysisyphus/dynamics/rattle.py +121 -0
- pysisyphus/dynamics/thermostats.py +128 -0
- pysisyphus/dynamics/wigner.py +266 -0
- pysisyphus/elem_data.py +3473 -0
- pysisyphus/exceptions.py +2 -0
- pysisyphus/filtertrj.py +69 -0
- pysisyphus/helpers.py +623 -0
- pysisyphus/helpers_pure.py +649 -0
- pysisyphus/init_logging.py +50 -0
- pysisyphus/intcoords/Bend.py +69 -0
- pysisyphus/intcoords/Bend2.py +25 -0
- pysisyphus/intcoords/BondedFragment.py +32 -0
- pysisyphus/intcoords/Cartesian.py +41 -0
- pysisyphus/intcoords/CartesianCoords.py +140 -0
- pysisyphus/intcoords/Coords.py +56 -0
- pysisyphus/intcoords/DLC.py +197 -0
- pysisyphus/intcoords/DistanceFunction.py +34 -0
- pysisyphus/intcoords/DummyImproper.py +70 -0
- pysisyphus/intcoords/DummyTorsion.py +72 -0
- pysisyphus/intcoords/LinearBend.py +105 -0
- pysisyphus/intcoords/LinearDisplacement.py +80 -0
- pysisyphus/intcoords/OutOfPlane.py +59 -0
- pysisyphus/intcoords/PrimTypes.py +286 -0
- pysisyphus/intcoords/Primitive.py +137 -0
- pysisyphus/intcoords/RedundantCoords.py +659 -0
- pysisyphus/intcoords/RobustTorsion.py +59 -0
- pysisyphus/intcoords/Rotation.py +147 -0
- pysisyphus/intcoords/Stretch.py +31 -0
- pysisyphus/intcoords/Torsion.py +101 -0
- pysisyphus/intcoords/Torsion2.py +25 -0
- pysisyphus/intcoords/Translation.py +45 -0
- pysisyphus/intcoords/__init__.py +61 -0
- pysisyphus/intcoords/augment_bonds.py +126 -0
- pysisyphus/intcoords/derivatives.py +10512 -0
- pysisyphus/intcoords/eval.py +80 -0
- pysisyphus/intcoords/exceptions.py +37 -0
- pysisyphus/intcoords/findiffs.py +48 -0
- pysisyphus/intcoords/generate_derivatives.py +414 -0
- pysisyphus/intcoords/helpers.py +235 -0
- pysisyphus/intcoords/logging_conf.py +10 -0
- pysisyphus/intcoords/mp_derivatives.py +10836 -0
- pysisyphus/intcoords/setup.py +962 -0
- pysisyphus/intcoords/setup_fast.py +176 -0
- pysisyphus/intcoords/update.py +272 -0
- pysisyphus/intcoords/valid.py +89 -0
- pysisyphus/interpolate/Geodesic.py +93 -0
- pysisyphus/interpolate/IDPP.py +55 -0
- pysisyphus/interpolate/Interpolator.py +116 -0
- pysisyphus/interpolate/LST.py +70 -0
- pysisyphus/interpolate/Redund.py +152 -0
- pysisyphus/interpolate/__init__.py +9 -0
- pysisyphus/interpolate/helpers.py +34 -0
- pysisyphus/io/__init__.py +22 -0
- pysisyphus/io/aomix.py +178 -0
- pysisyphus/io/cjson.py +24 -0
- pysisyphus/io/crd.py +101 -0
- pysisyphus/io/cube.py +220 -0
- pysisyphus/io/fchk.py +184 -0
- pysisyphus/io/hdf5.py +49 -0
- pysisyphus/io/hessian.py +72 -0
- pysisyphus/io/mol2.py +146 -0
- pysisyphus/io/molden.py +293 -0
- pysisyphus/io/orca.py +189 -0
- pysisyphus/io/pdb.py +269 -0
- pysisyphus/io/psf.py +79 -0
- pysisyphus/io/pubchem.py +31 -0
- pysisyphus/io/qcschema.py +34 -0
- pysisyphus/io/sdf.py +29 -0
- pysisyphus/io/xyz.py +61 -0
- pysisyphus/io/zmat.py +175 -0
- pysisyphus/irc/DWI.py +108 -0
- pysisyphus/irc/DampedVelocityVerlet.py +134 -0
- pysisyphus/irc/Euler.py +22 -0
- pysisyphus/irc/EulerPC.py +345 -0
- pysisyphus/irc/GonzalezSchlegel.py +187 -0
- pysisyphus/irc/IMKMod.py +164 -0
- pysisyphus/irc/IRC.py +878 -0
- pysisyphus/irc/IRCDummy.py +10 -0
- pysisyphus/irc/Instanton.py +307 -0
- pysisyphus/irc/LQA.py +53 -0
- pysisyphus/irc/ModeKill.py +136 -0
- pysisyphus/irc/ParamPlot.py +53 -0
- pysisyphus/irc/RK4.py +36 -0
- pysisyphus/irc/__init__.py +31 -0
- pysisyphus/irc/initial_displ.py +219 -0
- pysisyphus/linalg.py +411 -0
- pysisyphus/line_searches/Backtracking.py +88 -0
- pysisyphus/line_searches/HagerZhang.py +184 -0
- pysisyphus/line_searches/LineSearch.py +232 -0
- pysisyphus/line_searches/StrongWolfe.py +108 -0
- pysisyphus/line_searches/__init__.py +9 -0
- pysisyphus/line_searches/interpol.py +15 -0
- pysisyphus/modefollow/NormalMode.py +40 -0
- pysisyphus/modefollow/__init__.py +10 -0
- pysisyphus/modefollow/davidson.py +199 -0
- pysisyphus/modefollow/lanczos.py +95 -0
- pysisyphus/optimizers/BFGS.py +99 -0
- pysisyphus/optimizers/BacktrackingOptimizer.py +113 -0
- pysisyphus/optimizers/ConjugateGradient.py +98 -0
- pysisyphus/optimizers/CubicNewton.py +75 -0
- pysisyphus/optimizers/FIRE.py +113 -0
- pysisyphus/optimizers/HessianOptimizer.py +1176 -0
- pysisyphus/optimizers/LBFGS.py +228 -0
- pysisyphus/optimizers/LayerOpt.py +411 -0
- pysisyphus/optimizers/MicroOptimizer.py +169 -0
- pysisyphus/optimizers/NCOptimizer.py +90 -0
- pysisyphus/optimizers/Optimizer.py +1084 -0
- pysisyphus/optimizers/PreconLBFGS.py +260 -0
- pysisyphus/optimizers/PreconSteepestDescent.py +7 -0
- pysisyphus/optimizers/QuickMin.py +74 -0
- pysisyphus/optimizers/RFOptimizer.py +181 -0
- pysisyphus/optimizers/RSA.py +99 -0
- pysisyphus/optimizers/StabilizedQNMethod.py +248 -0
- pysisyphus/optimizers/SteepestDescent.py +23 -0
- pysisyphus/optimizers/StringOptimizer.py +173 -0
- pysisyphus/optimizers/__init__.py +41 -0
- pysisyphus/optimizers/closures.py +301 -0
- pysisyphus/optimizers/cls_map.py +58 -0
- pysisyphus/optimizers/exceptions.py +6 -0
- pysisyphus/optimizers/gdiis.py +280 -0
- pysisyphus/optimizers/guess_hessians.py +311 -0
- pysisyphus/optimizers/hessian_updates.py +355 -0
- pysisyphus/optimizers/poly_fit.py +285 -0
- pysisyphus/optimizers/precon.py +153 -0
- pysisyphus/optimizers/restrict_step.py +24 -0
- pysisyphus/pack.py +172 -0
- pysisyphus/peakdetect.py +948 -0
- pysisyphus/plot.py +1031 -0
- pysisyphus/run.py +2106 -0
- pysisyphus/socket_helper.py +74 -0
- pysisyphus/stocastic/FragmentKick.py +132 -0
- pysisyphus/stocastic/Kick.py +81 -0
- pysisyphus/stocastic/Pipeline.py +303 -0
- pysisyphus/stocastic/__init__.py +21 -0
- pysisyphus/stocastic/align.py +127 -0
- pysisyphus/testing.py +96 -0
- pysisyphus/thermo.py +156 -0
- pysisyphus/trj.py +824 -0
- pysisyphus/tsoptimizers/RSIRFOptimizer.py +56 -0
- pysisyphus/tsoptimizers/RSPRFOptimizer.py +182 -0
- pysisyphus/tsoptimizers/TRIM.py +59 -0
- pysisyphus/tsoptimizers/TSHessianOptimizer.py +463 -0
- pysisyphus/tsoptimizers/__init__.py +23 -0
- pysisyphus/wavefunction/Basis.py +239 -0
- pysisyphus/wavefunction/DIIS.py +76 -0
- pysisyphus/wavefunction/__init__.py +25 -0
- pysisyphus/wavefunction/build_ext.py +42 -0
- pysisyphus/wavefunction/cart2sph.py +190 -0
- pysisyphus/wavefunction/diabatization.py +304 -0
- pysisyphus/wavefunction/excited_states.py +435 -0
- pysisyphus/wavefunction/gen_ints.py +1811 -0
- pysisyphus/wavefunction/helpers.py +104 -0
- pysisyphus/wavefunction/ints/__init__.py +0 -0
- pysisyphus/wavefunction/ints/boys.py +193 -0
- pysisyphus/wavefunction/ints/boys_table_N_64_xasym_27.1_step_0.01.npy +0 -0
- pysisyphus/wavefunction/ints/cart_gto3d.py +176 -0
- pysisyphus/wavefunction/ints/coulomb3d.py +25928 -0
- pysisyphus/wavefunction/ints/diag_quadrupole3d.py +10036 -0
- pysisyphus/wavefunction/ints/dipole3d.py +8762 -0
- pysisyphus/wavefunction/ints/int2c2e3d.py +7198 -0
- pysisyphus/wavefunction/ints/int3c2e3d_sph.py +65040 -0
- pysisyphus/wavefunction/ints/kinetic3d.py +8240 -0
- pysisyphus/wavefunction/ints/ovlp3d.py +3777 -0
- pysisyphus/wavefunction/ints/quadrupole3d.py +15054 -0
- pysisyphus/wavefunction/ints/self_ovlp3d.py +198 -0
- pysisyphus/wavefunction/localization.py +458 -0
- pysisyphus/wavefunction/multipole.py +159 -0
- pysisyphus/wavefunction/normalization.py +36 -0
- pysisyphus/wavefunction/pop_analysis.py +134 -0
- pysisyphus/wavefunction/shells.py +1171 -0
- pysisyphus/wavefunction/wavefunction.py +504 -0
- pysisyphus/wrapper/__init__.py +11 -0
- pysisyphus/wrapper/exceptions.py +2 -0
- pysisyphus/wrapper/jmol.py +120 -0
- pysisyphus/wrapper/mwfn.py +169 -0
- pysisyphus/wrapper/packmol.py +71 -0
- pysisyphus/xyzloader.py +168 -0
- pysisyphus/yaml_mods.py +45 -0
- thermoanalysis/LICENSE +674 -0
- thermoanalysis/QCData.py +244 -0
- thermoanalysis/__init__.py +0 -0
- thermoanalysis/config.py +3 -0
- thermoanalysis/constants.py +20 -0
- 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
|
+
)
|