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,116 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pysisyphus.Geometry import Geometry
|
|
4
|
+
from pysisyphus.helpers import align_geoms
|
|
5
|
+
from pysisyphus.xyzloader import write_geoms_to_trj
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Interpolator:
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
geoms,
|
|
12
|
+
between,
|
|
13
|
+
extrapolate=0,
|
|
14
|
+
extrapolate_before=0,
|
|
15
|
+
extrapolate_after=0,
|
|
16
|
+
extrapolate_damp=1.0,
|
|
17
|
+
align=False,
|
|
18
|
+
):
|
|
19
|
+
self.geoms = geoms
|
|
20
|
+
self.between = between
|
|
21
|
+
self.extrapolate = extrapolate
|
|
22
|
+
self.extrapolate_before = (
|
|
23
|
+
extrapolate_before if extrapolate_before else self.extrapolate
|
|
24
|
+
)
|
|
25
|
+
self.extrapolate_after = (
|
|
26
|
+
extrapolate_after if extrapolate_after else self.extrapolate
|
|
27
|
+
)
|
|
28
|
+
self.extrapolate_damp = extrapolate_damp
|
|
29
|
+
one_atom_geom = any([len(geom.atoms) == 1 for geom in geoms])
|
|
30
|
+
# Don't try to align one atom species
|
|
31
|
+
self.align = align and not one_atom_geom
|
|
32
|
+
|
|
33
|
+
assert len(geoms) >= 2, "Need at least two geometries to interpolate!"
|
|
34
|
+
|
|
35
|
+
# Check for consistent atom ordering
|
|
36
|
+
for i, geom in enumerate(self.geoms[:-1]):
|
|
37
|
+
next_geom = self.geoms[i + 1]
|
|
38
|
+
atoms = geom.atoms
|
|
39
|
+
next_atoms = next_geom.atoms
|
|
40
|
+
assert len(atoms) == len(
|
|
41
|
+
next_atoms
|
|
42
|
+
), f"Geometries {i} and {i+1} have a different number of atoms!"
|
|
43
|
+
assert (
|
|
44
|
+
atoms == next_atoms
|
|
45
|
+
), f"Different atom ordering in geometries {i} and {i+1}!"
|
|
46
|
+
|
|
47
|
+
self.atoms = self.geoms[0].atoms
|
|
48
|
+
if self.align:
|
|
49
|
+
align_geoms(geoms)
|
|
50
|
+
self.all_geoms = None
|
|
51
|
+
|
|
52
|
+
def interpolate_all(self):
|
|
53
|
+
all_geoms = list()
|
|
54
|
+
|
|
55
|
+
if self.extrapolate_before:
|
|
56
|
+
print("Extrapolating before")
|
|
57
|
+
geoms_extrapol_before = self.interpolate(
|
|
58
|
+
self.geoms[0],
|
|
59
|
+
self.geoms[1],
|
|
60
|
+
interpolate_only=self.extrapolate_before,
|
|
61
|
+
extrapolate=True,
|
|
62
|
+
)
|
|
63
|
+
all_geoms += geoms_extrapol_before[::-1]
|
|
64
|
+
|
|
65
|
+
print("Interpolating between")
|
|
66
|
+
# Interpolate between all pairs of geometries
|
|
67
|
+
for i, initial_geom in enumerate(self.geoms[:-1]):
|
|
68
|
+
final_geom = self.geoms[i + 1]
|
|
69
|
+
interpolated_geoms = self.interpolate(initial_geom, final_geom)
|
|
70
|
+
assert len(interpolated_geoms) == self.between, (
|
|
71
|
+
"Something is wrong with the number of interpolated "
|
|
72
|
+
"geometries. Maybe you accidentally also return the "
|
|
73
|
+
"initial and final geometry?"
|
|
74
|
+
)
|
|
75
|
+
all_geoms.append(self.geoms[i])
|
|
76
|
+
all_geoms.extend(interpolated_geoms)
|
|
77
|
+
# As we only added the i-th geometry and the new interpolated
|
|
78
|
+
# geometries of every geometry pair we also have to add the last
|
|
79
|
+
# ((i+1)-th) geometry at the end.
|
|
80
|
+
all_geoms.append(self.geoms[-1])
|
|
81
|
+
|
|
82
|
+
print("Extrapolate between")
|
|
83
|
+
if self.extrapolate_after:
|
|
84
|
+
geoms_extrapol_after = self.interpolate(
|
|
85
|
+
self.geoms[-1],
|
|
86
|
+
self.geoms[-2],
|
|
87
|
+
interpolate_only=self.extrapolate_after,
|
|
88
|
+
extrapolate=True,
|
|
89
|
+
)
|
|
90
|
+
all_geoms += geoms_extrapol_after
|
|
91
|
+
|
|
92
|
+
self.all_geoms = all_geoms
|
|
93
|
+
if self.align:
|
|
94
|
+
align_geoms(self.all_geoms)
|
|
95
|
+
return all_geoms
|
|
96
|
+
|
|
97
|
+
def interpolate(
|
|
98
|
+
self, initial_geom, final_geom, interpolate_only=0, extrapolate=False
|
|
99
|
+
):
|
|
100
|
+
initial_coords = initial_geom.coords
|
|
101
|
+
|
|
102
|
+
# Linear interpolation
|
|
103
|
+
step = (final_geom.coords - initial_geom.coords) / (self.between + 1)
|
|
104
|
+
if extrapolate:
|
|
105
|
+
step *= -1
|
|
106
|
+
step *= self.extrapolate_damp
|
|
107
|
+
# When we extrapolate we probably want a number of geometries that is
|
|
108
|
+
# different from self.between
|
|
109
|
+
interpolations = interpolate_only if interpolate_only else self.between
|
|
110
|
+
# initial + i*step
|
|
111
|
+
i_array = np.arange(1, interpolations + 1)
|
|
112
|
+
new_coords = initial_coords + i_array[:, None] * step
|
|
113
|
+
return [Geometry(self.atoms, nc) for nc in new_coords]
|
|
114
|
+
|
|
115
|
+
def all_geoms_to_trj(self, trj_fn):
|
|
116
|
+
write_geoms_to_trj(self.all_geoms, trj_fn)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.spatial.distance import pdist
|
|
3
|
+
from scipy.optimize import minimize
|
|
4
|
+
|
|
5
|
+
from pysisyphus.Geometry import Geometry
|
|
6
|
+
from pysisyphus.interpolate.Interpolator import Interpolator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# [1] https://www.sciencedirect.com/science/article/pii/S0927025603001113
|
|
10
|
+
# [2] https://pubs.acs.org/doi/pdf/10.1021/ct200654u
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LST(Interpolator):
|
|
14
|
+
def __init__(self, *args, align=True, gtol=1e-4, silent=False, **kwargs):
|
|
15
|
+
super().__init__(*args, align=align, **kwargs)
|
|
16
|
+
|
|
17
|
+
self.gtol = float(gtol)
|
|
18
|
+
self.silent = silent
|
|
19
|
+
|
|
20
|
+
def cost_function(self, wa_c, f, rab, wab):
|
|
21
|
+
wa_c = wa_c.reshape(-1, 3)
|
|
22
|
+
rab_c = pdist(wa_c)
|
|
23
|
+
|
|
24
|
+
rab_i = rab(f)
|
|
25
|
+
wa_i = wab(f)
|
|
26
|
+
|
|
27
|
+
first_term = np.sum(((rab_i - rab_c) ** 2) / (rab_i**4))
|
|
28
|
+
second_term = 1e-6 * np.sum((wa_i - wa_c) ** 2)
|
|
29
|
+
return first_term + second_term
|
|
30
|
+
|
|
31
|
+
def interpolate(self, initial_geom, final_geom, **kwargs):
|
|
32
|
+
coords3d = np.array((initial_geom.coords3d, final_geom.coords3d))
|
|
33
|
+
# Calculate the condensed distances matrices
|
|
34
|
+
pdists = [pdist(c3d) for c3d in coords3d]
|
|
35
|
+
|
|
36
|
+
def rab_(f, pdist_r, pdist_p):
|
|
37
|
+
"""Difference in internuclear distances."""
|
|
38
|
+
return (1 - f) * pdist_r + f * pdist_p
|
|
39
|
+
|
|
40
|
+
rab = lambda f: rab_(f, pdists[0], pdists[1])
|
|
41
|
+
|
|
42
|
+
def wab_(f, coords_r, coords_p):
|
|
43
|
+
"""Difference in actual cartesian coordinates."""
|
|
44
|
+
return (1 - f) * coords_r + f * coords_p
|
|
45
|
+
|
|
46
|
+
wab = lambda f: wab_(f, coords3d[0], coords3d[1])
|
|
47
|
+
|
|
48
|
+
interpolated_geoms = list()
|
|
49
|
+
minimize_kwargs = {
|
|
50
|
+
"method": "L-BFGS-B",
|
|
51
|
+
"options": {
|
|
52
|
+
"gtol": self.gtol,
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
# We only have to interpolate between the two provided geometries.
|
|
56
|
+
# So we consider the total number of geometries (self.between + 2)
|
|
57
|
+
# to get the correct spacing, but we neglect the first and the last
|
|
58
|
+
# number (0 and 1), as they correspond to the two already known geometries.
|
|
59
|
+
for i, f in enumerate(np.linspace(0, 1, self.between + 2)[1:-1], 1):
|
|
60
|
+
x0_flat = wab(f)
|
|
61
|
+
res = minimize(
|
|
62
|
+
self.cost_function,
|
|
63
|
+
x0=x0_flat.flatten(),
|
|
64
|
+
args=(f, rab, wab),
|
|
65
|
+
**minimize_kwargs,
|
|
66
|
+
)
|
|
67
|
+
if not self.silent:
|
|
68
|
+
print(f"{i:03d}/{self.between:03d}: f={f:.04f}, success: {res.success}")
|
|
69
|
+
interpolated_geoms.append(Geometry(self.atoms, res.x))
|
|
70
|
+
return interpolated_geoms
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pysisyphus.Geometry import Geometry
|
|
6
|
+
from pysisyphus.interpolate.Interpolator import Interpolator
|
|
7
|
+
from pysisyphus.intcoords.exceptions import (
|
|
8
|
+
DifferentPrimitivesException,
|
|
9
|
+
RebuiltInternalsException,
|
|
10
|
+
)
|
|
11
|
+
from pysisyphus.intcoords.helpers import get_tangent, form_coordinate_union
|
|
12
|
+
from pysisyphus.xyzloader import write_geoms_to_trj
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Redund(Interpolator):
|
|
16
|
+
def __init__(self, *args, align=True, rebuild_geoms=True, **kwargs):
|
|
17
|
+
super().__init__(*args, align=align, **kwargs)
|
|
18
|
+
|
|
19
|
+
self.rebuild_geoms = rebuild_geoms
|
|
20
|
+
if self.rebuild_geoms:
|
|
21
|
+
self.geoms = [
|
|
22
|
+
Geometry(geom.atoms, geom.cart_coords, coord_type="redund")
|
|
23
|
+
for geom in self.geoms
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
def dump_progress(self, geoms, out_fn="redund_interpol_fail_trj.xyz"):
|
|
27
|
+
write_geoms_to_trj(geoms, out_fn)
|
|
28
|
+
print(f"Dumped interpolation progress to '{out_fn}'.")
|
|
29
|
+
|
|
30
|
+
def interpolate(
|
|
31
|
+
self,
|
|
32
|
+
initial_geom,
|
|
33
|
+
final_geom,
|
|
34
|
+
interpolate_only=0,
|
|
35
|
+
extrapolate=False,
|
|
36
|
+
typed_prims=None,
|
|
37
|
+
):
|
|
38
|
+
print(f"No. of primitives at initial structure: {initial_geom.coords.size}")
|
|
39
|
+
print(f"No. of primitives at final structure: {final_geom.coords.size}")
|
|
40
|
+
|
|
41
|
+
if typed_prims is None:
|
|
42
|
+
typed_prims = form_coordinate_union(initial_geom, final_geom)
|
|
43
|
+
print(f"Union of primitives: {len(typed_prims)}")
|
|
44
|
+
else:
|
|
45
|
+
print(f"Using supplied primitive internals ({len(typed_prims)}).")
|
|
46
|
+
|
|
47
|
+
# Recreate geometries with consistent set of internal coordinates
|
|
48
|
+
geom1 = Geometry(
|
|
49
|
+
initial_geom.atoms,
|
|
50
|
+
initial_geom.cart_coords,
|
|
51
|
+
coord_type="redund",
|
|
52
|
+
coord_kwargs={
|
|
53
|
+
"typed_prims": typed_prims,
|
|
54
|
+
"recalc_B": True,
|
|
55
|
+
},
|
|
56
|
+
)
|
|
57
|
+
geom2 = Geometry(
|
|
58
|
+
final_geom.atoms,
|
|
59
|
+
final_geom.cart_coords,
|
|
60
|
+
coord_type="redund",
|
|
61
|
+
coord_kwargs={
|
|
62
|
+
"typed_prims": typed_prims,
|
|
63
|
+
"recalc_B": True,
|
|
64
|
+
},
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
dihedral_indices = geom1.internal.dihedral_indices
|
|
68
|
+
initial_tangent = get_tangent(geom1.coords, geom2.coords, dihedral_indices)
|
|
69
|
+
initial_diff = np.linalg.norm(initial_tangent)
|
|
70
|
+
approx_step_size = initial_diff / (self.between + 1)
|
|
71
|
+
final_prims = geom2.internal.prim_coords
|
|
72
|
+
|
|
73
|
+
geoms = [
|
|
74
|
+
geom1,
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
def restart(new_geom):
|
|
78
|
+
interpolate_kwargs = {
|
|
79
|
+
"initial_geom": initial_geom,
|
|
80
|
+
"final_geom": final_geom,
|
|
81
|
+
"extrapolate": extrapolate,
|
|
82
|
+
"interpolate_only": interpolate_only,
|
|
83
|
+
}
|
|
84
|
+
return self.restart_interpolate(geoms, new_geom, interpolate_kwargs)
|
|
85
|
+
|
|
86
|
+
# initial_geom, final_geom, geoms, new_geom)
|
|
87
|
+
|
|
88
|
+
interpolations = interpolate_only if interpolate_only else self.between
|
|
89
|
+
ip_ex = "Extrapolating" if extrapolate else "Interpolating"
|
|
90
|
+
for i in range(interpolations):
|
|
91
|
+
print(f"{ip_ex} {i+1:03d}/{interpolations:03d}")
|
|
92
|
+
new_geom = geoms[-1].copy()
|
|
93
|
+
# Try to use the target primtive internals (final_prims) to calculate
|
|
94
|
+
# a tangent at the current, new geometry. As some primitives may be
|
|
95
|
+
# invalid at 'new_geom', DifferentPrimitivesException may be raised.
|
|
96
|
+
try:
|
|
97
|
+
prim_tangent = get_tangent(
|
|
98
|
+
new_geom.coords, final_prims, dihedral_indices
|
|
99
|
+
)
|
|
100
|
+
# If this is raised we update our target primitives and try to continue
|
|
101
|
+
# with them.
|
|
102
|
+
except DifferentPrimitivesException:
|
|
103
|
+
# return self.restart_interpolate(initial_geom, final_geom, new_geom)
|
|
104
|
+
return restart(new_geom)
|
|
105
|
+
if extrapolate:
|
|
106
|
+
prim_tangent *= -1
|
|
107
|
+
approx_step_size *= self.extrapolate_damp
|
|
108
|
+
|
|
109
|
+
step = self.step_along_tangent(new_geom, prim_tangent, approx_step_size)
|
|
110
|
+
try:
|
|
111
|
+
new_coords = new_geom.coords + step
|
|
112
|
+
# Will be raised when the sizes of both vectors differ
|
|
113
|
+
except ValueError:
|
|
114
|
+
# return self.restart_interpolate(initial_geom, final_geom, new_geom)
|
|
115
|
+
return restart(new_geom)
|
|
116
|
+
|
|
117
|
+
# The current primitives may also break down when a step along the
|
|
118
|
+
# tangent is taken.
|
|
119
|
+
try:
|
|
120
|
+
new_geom.coords = new_coords
|
|
121
|
+
except RebuiltInternalsException:
|
|
122
|
+
# return self.restart_interpolate(initial_geom, final_geom, new_geom)
|
|
123
|
+
return restart(new_geom)
|
|
124
|
+
|
|
125
|
+
geoms.append(new_geom)
|
|
126
|
+
sys.stdout.flush()
|
|
127
|
+
|
|
128
|
+
print()
|
|
129
|
+
return geoms[1:]
|
|
130
|
+
|
|
131
|
+
# def restart_interpolate(self, initial_geom, final_geom, geoms, new_geom):
|
|
132
|
+
def restart_interpolate(self, geoms, new_geom, interpolate_kwargs):
|
|
133
|
+
new_typed_prims = new_geom.internal.typed_prims
|
|
134
|
+
print(
|
|
135
|
+
f"Encountered breakdown of current primitive internals.\n"
|
|
136
|
+
"Restarting interpolation with reduced number of internals."
|
|
137
|
+
)
|
|
138
|
+
self.dump_progress(geoms, out_fn=f"redund_interpol_fail_trj.xyz")
|
|
139
|
+
print()
|
|
140
|
+
# Recursive call with reduced set of primitive internals
|
|
141
|
+
return self.interpolate(**interpolate_kwargs, typed_prims=new_typed_prims)
|
|
142
|
+
|
|
143
|
+
def step_along_tangent(self, geom, prim_tangent, step_size):
|
|
144
|
+
# Form active set
|
|
145
|
+
B = geom.internal.B_prim
|
|
146
|
+
G = B.dot(B.T)
|
|
147
|
+
eigvals, eigvectors = np.linalg.eigh(G)
|
|
148
|
+
U = eigvectors[:, np.abs(eigvals) > 1e-6]
|
|
149
|
+
reduced_tangent = (np.einsum("i,ij->j", prim_tangent, U) * U).sum(axis=1)
|
|
150
|
+
reduced_tangent /= np.linalg.norm(reduced_tangent)
|
|
151
|
+
step = step_size * reduced_tangent
|
|
152
|
+
return step
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from pysisyphus.interpolate import IDPP, LST, Interpolator, Redund, Geodesic
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
INTERPOLATE = {
|
|
5
|
+
"idpp": IDPP.IDPP,
|
|
6
|
+
"lst": LST.LST,
|
|
7
|
+
"redund": Redund.Redund,
|
|
8
|
+
"linear": Interpolator.Interpolator,
|
|
9
|
+
"geodesic": Geodesic.Geodesic,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def interpolate(initial_geom, final_geom, between, kind="linear",
|
|
14
|
+
only_between=False, align=False, interpol_kwargs=None):
|
|
15
|
+
if interpol_kwargs is None:
|
|
16
|
+
interpol_kwargs = {}
|
|
17
|
+
""" only_between: return only the interpolated images."""
|
|
18
|
+
interpolate_class = INTERPOLATE[kind]
|
|
19
|
+
interpolator = interpolate_class((initial_geom, final_geom), between,
|
|
20
|
+
align=align, **interpol_kwargs)
|
|
21
|
+
if only_between:
|
|
22
|
+
return interpolator.interpolate(initial_geom, final_geom)
|
|
23
|
+
else:
|
|
24
|
+
return interpolator.interpolate_all()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def interpolate_all(geoms, between, kind="linear", align=False, **interpol_kwargs):
|
|
28
|
+
if (between == 0) or (kind is None):
|
|
29
|
+
return geoms
|
|
30
|
+
|
|
31
|
+
interpolate_class = INTERPOLATE[kind]
|
|
32
|
+
interpolator = interpolate_class(geoms, between, align=align, **interpol_kwargs)
|
|
33
|
+
|
|
34
|
+
return interpolator.interpolate_all()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
__all__ = [
|
|
2
|
+
"geom_from_cjson",
|
|
3
|
+
"geom_from_crd",
|
|
4
|
+
"geom_from_hessian",
|
|
5
|
+
"geom_from_mol2",
|
|
6
|
+
"geom_from_pdb",
|
|
7
|
+
"geom_from_zmat",
|
|
8
|
+
"geom_from_qcschema",
|
|
9
|
+
"geoms_from_xyz",
|
|
10
|
+
"save_hessian",
|
|
11
|
+
"save_third_deriv",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
from pysisyphus.io.cjson import geom_from_cjson
|
|
16
|
+
from pysisyphus.io.crd import geom_from_crd, geom_to_crd_str
|
|
17
|
+
from pysisyphus.io.hessian import save_hessian, save_third_deriv, geom_from_hessian
|
|
18
|
+
from pysisyphus.io.mol2 import geom_from_mol2
|
|
19
|
+
from pysisyphus.io.pdb import geom_from_pdb
|
|
20
|
+
from pysisyphus.io.qcschema import geom_from_qcschema
|
|
21
|
+
from pysisyphus.io.xyz import geoms_from_xyz, geoms_from_inline_xyz, parse_xyz
|
|
22
|
+
from pysisyphus.io.zmat import geom_from_zmat, geom_from_zmat_fn
|
pysisyphus/io/aomix.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pyparsing as pp
|
|
3
|
+
|
|
4
|
+
from pysisyphus.elem_data import ATOMIC_NUMBERS, nuc_charges_for_atoms
|
|
5
|
+
from pysisyphus.helpers_pure import file_or_str
|
|
6
|
+
from pysisyphus.wavefunction import get_l, Shell, AOMixShells, Wavefunction
|
|
7
|
+
from pysisyphus.wavefunction.helpers import BFType
|
|
8
|
+
|
|
9
|
+
AOMIX_EXTS = ".in"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@file_or_str(*AOMIX_EXTS)
|
|
13
|
+
def parse_aomix(text):
|
|
14
|
+
real = pp.common.real
|
|
15
|
+
sreal = pp.common.sci_real
|
|
16
|
+
int_ = pp.common.integer
|
|
17
|
+
header = pp.CaselessLiteral("[AOMix Format]")
|
|
18
|
+
title = pp.CaselessKeyword("[Title]")
|
|
19
|
+
energy = pp.Suppress(pp.CaselessLiteral("[SCF Energy / Hartree]")) + sreal
|
|
20
|
+
xyz = pp.Group(sreal + sreal + sreal)
|
|
21
|
+
atom_line = pp.Group(
|
|
22
|
+
pp.Word(pp.alphas).set_results_name("atom")
|
|
23
|
+
+ int_.set_results_name("id")
|
|
24
|
+
+ int_.set_results_name("atom_num")
|
|
25
|
+
+ xyz.set_results_name("xyz")
|
|
26
|
+
)
|
|
27
|
+
atoms = (
|
|
28
|
+
pp.Suppress(pp.CaselessLiteral("[Atoms]"))
|
|
29
|
+
+ pp.Optional(pp.CaselessLiteral("AU")).set_results_name("unit")
|
|
30
|
+
+ pp.OneOrMore(atom_line).set_results_name("atom_lines")
|
|
31
|
+
)
|
|
32
|
+
prim_gto = pp.Group(sreal + sreal)
|
|
33
|
+
contr_gto = pp.Group(
|
|
34
|
+
pp.Word(pp.alphas).set_results_name("l")
|
|
35
|
+
+ int_.set_results_name("contr_depth")
|
|
36
|
+
+ real
|
|
37
|
+
+ pp.OneOrMore(prim_gto).set_results_name("prim_gtos")
|
|
38
|
+
)
|
|
39
|
+
center_contr_gto = pp.Group(
|
|
40
|
+
int_.set_results_name("center")
|
|
41
|
+
+ int_
|
|
42
|
+
+ pp.OneOrMore(contr_gto).set_results_name("contr_gtos")
|
|
43
|
+
)
|
|
44
|
+
gtos = pp.CaselessLiteral("[GTO]") + pp.OneOrMore(
|
|
45
|
+
center_contr_gto
|
|
46
|
+
).set_results_name("center_gtos")
|
|
47
|
+
ao_label = pp.Word(pp.alphanums)
|
|
48
|
+
mo_line = pp.Suppress(int_ + int_ + pp.Word(pp.alphas) + int_ + ao_label) + sreal
|
|
49
|
+
sym_label = int_ + pp.one_of(("a", "b"), caseless=True)
|
|
50
|
+
mo = pp.Group(
|
|
51
|
+
pp.CaselessLiteral("Sym=")
|
|
52
|
+
+ sym_label.set_results_name("sym_label")
|
|
53
|
+
+ pp.CaselessLiteral("Ene=")
|
|
54
|
+
+ sreal.set_results_name("ene")
|
|
55
|
+
+ pp.CaselessLiteral("Spin=")
|
|
56
|
+
+ pp.one_of(("Alpha", "Beta"), caseless=True).set_results_name("spin")
|
|
57
|
+
+ pp.CaselessLiteral("Occup=")
|
|
58
|
+
+ sreal.set_results_name("occup")
|
|
59
|
+
+ pp.Group(pp.OneOrMore(mo_line)).set_results_name("coeffs")
|
|
60
|
+
)
|
|
61
|
+
mos = pp.CaselessLiteral("[MO]") + pp.OneOrMore(mo).set_results_name("mos")
|
|
62
|
+
|
|
63
|
+
parser = (
|
|
64
|
+
header
|
|
65
|
+
+ pp.Optional(title).set_results_name("title")
|
|
66
|
+
+ pp.Optional(energy).set_results_name("energy")
|
|
67
|
+
+ atoms
|
|
68
|
+
+ gtos
|
|
69
|
+
+ mos
|
|
70
|
+
)
|
|
71
|
+
result = parser.parseString(text)
|
|
72
|
+
as_dict = result.asDict()
|
|
73
|
+
|
|
74
|
+
return as_dict
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def shells_from_aomix_dict(aomix_dict):
|
|
78
|
+
atom_lines = aomix_dict["atom_lines"]
|
|
79
|
+
center_gtos = aomix_dict["center_gtos"]
|
|
80
|
+
_shells = list()
|
|
81
|
+
for atom_line, cgtos in zip(atom_lines, center_gtos):
|
|
82
|
+
atomic_num = ATOMIC_NUMBERS[atom_line["atom"].lower()]
|
|
83
|
+
center_ind = cgtos["center"]
|
|
84
|
+
assert atom_line["id"] == center_ind
|
|
85
|
+
center_ind -= 1 # Start from 0 internally
|
|
86
|
+
center = np.array(atom_line["xyz"])
|
|
87
|
+
for cgto in cgtos["contr_gtos"]:
|
|
88
|
+
exps, coeffs = zip(*cgto["prim_gtos"])
|
|
89
|
+
exps = np.array(exps)
|
|
90
|
+
coeffs = np.array(coeffs)
|
|
91
|
+
L = get_l(cgto["l"])
|
|
92
|
+
shell = Shell(
|
|
93
|
+
L=L,
|
|
94
|
+
atomic_num=atomic_num,
|
|
95
|
+
center=center,
|
|
96
|
+
coeffs=coeffs,
|
|
97
|
+
exps=exps,
|
|
98
|
+
center_ind=center_ind,
|
|
99
|
+
)
|
|
100
|
+
_shells.append(shell)
|
|
101
|
+
shells = AOMixShells(_shells)
|
|
102
|
+
return shells
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def wavefunction_from_aomix_dict(aomix_dict, **wf_kwargs):
|
|
106
|
+
shells = shells_from_aomix_dict(aomix_dict)
|
|
107
|
+
|
|
108
|
+
atoms = list()
|
|
109
|
+
coords3d = list()
|
|
110
|
+
for atom_line in aomix_dict["atom_lines"]:
|
|
111
|
+
atoms.append(atom_line["atom"].lower())
|
|
112
|
+
coords3d.append(atom_line["xyz"])
|
|
113
|
+
atoms = tuple(atoms)
|
|
114
|
+
coords = np.array(coords3d).flatten()
|
|
115
|
+
|
|
116
|
+
occ_a = 0
|
|
117
|
+
occ_b = 0
|
|
118
|
+
unrestricted = False
|
|
119
|
+
C_a = list()
|
|
120
|
+
C_b = list()
|
|
121
|
+
for mo in aomix_dict["mos"]:
|
|
122
|
+
spin = mo["spin"].lower()
|
|
123
|
+
occup = mo["occup"]
|
|
124
|
+
coeffs = mo["coeffs"]
|
|
125
|
+
if spin == "alpha":
|
|
126
|
+
occ_a += occup
|
|
127
|
+
C_a.append(coeffs)
|
|
128
|
+
elif spin == "beta":
|
|
129
|
+
occ_b += occup
|
|
130
|
+
C_b.append(coeffs)
|
|
131
|
+
else:
|
|
132
|
+
raise Exception(f"Unknown {spin=}!")
|
|
133
|
+
|
|
134
|
+
if not unrestricted:
|
|
135
|
+
unrestricted = spin == "beta"
|
|
136
|
+
occ_a = int(occ_a)
|
|
137
|
+
occ_b = int(occ_b)
|
|
138
|
+
if not unrestricted:
|
|
139
|
+
C_b = C_a.copy()
|
|
140
|
+
occ_a = occ_b = occ_a // 2
|
|
141
|
+
mult = 1
|
|
142
|
+
else:
|
|
143
|
+
mult = (occ_a - occ_b) + 1
|
|
144
|
+
|
|
145
|
+
nuc_charge = nuc_charges_for_atoms(atoms).sum()
|
|
146
|
+
charge = nuc_charge - occ_a - occ_b
|
|
147
|
+
C = np.array((np.transpose(C_a), np.transpose(C_b)))
|
|
148
|
+
_wf_kwargs = {
|
|
149
|
+
"atoms": atoms,
|
|
150
|
+
"coords": coords,
|
|
151
|
+
"charge": charge,
|
|
152
|
+
"mult": mult,
|
|
153
|
+
"unrestricted": unrestricted,
|
|
154
|
+
"occ": (occ_a, occ_b),
|
|
155
|
+
"C": C,
|
|
156
|
+
"bf_type": BFType.CARTESIAN,
|
|
157
|
+
"shells": shells,
|
|
158
|
+
**wf_kwargs,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
_wf_kwargs.update(wf_kwargs)
|
|
162
|
+
return Wavefunction(**_wf_kwargs)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@file_or_str(*AOMIX_EXTS)
|
|
166
|
+
def shells_from_aomix(text):
|
|
167
|
+
aomix_dict = parse_aomix(text)
|
|
168
|
+
return shells_from_aomix_dict(aomix_dict)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@file_or_str(*AOMIX_EXTS)
|
|
172
|
+
def wavefunction_from_aomix(text, **wf_kwargs):
|
|
173
|
+
from time import time
|
|
174
|
+
start = time()
|
|
175
|
+
aomix_dict = parse_aomix(text)
|
|
176
|
+
dur = time() - start
|
|
177
|
+
print("dur", dur)
|
|
178
|
+
return wavefunction_from_aomix_dict(aomix_dict, **wf_kwargs)
|
pysisyphus/io/cjson.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pysisyphus.constants import ANG2BOHR
|
|
6
|
+
from pysisyphus.Geometry import Geometry
|
|
7
|
+
from pysisyphus.elem_data import INV_ATOMIC_NUMBERS
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def parse_cjson(fn):
|
|
11
|
+
with open(fn) as handle:
|
|
12
|
+
cml = json.load(handle)
|
|
13
|
+
atms = cml["atoms"]
|
|
14
|
+
coords = np.array(atms["coords"]["3d"], dtype=float) * ANG2BOHR
|
|
15
|
+
atom_nums = atms["elements"]["number"]
|
|
16
|
+
atoms = tuple([INV_ATOMIC_NUMBERS[num].capitalize() for num in atom_nums])
|
|
17
|
+
|
|
18
|
+
return atoms, coords.flatten()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def geom_from_cjson(fn, **kwargs):
|
|
22
|
+
atoms, coords = parse_cjson(fn)
|
|
23
|
+
geom = Geometry(atoms, coords.flatten(), **kwargs)
|
|
24
|
+
return geom
|