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,463 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
import h5py
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from pysisyphus.Geometry import Geometry
|
|
7
|
+
from pysisyphus.helpers_pure import log
|
|
8
|
+
from pysisyphus.intcoords.augment_bonds import augment_bonds
|
|
9
|
+
from pysisyphus.intcoords.PrimTypes import normalize_prim_input, normalize_prim_inputs
|
|
10
|
+
from pysisyphus.optimizers import poly_fit
|
|
11
|
+
from pysisyphus.optimizers.guess_hessians import ts_hessian, HessInit
|
|
12
|
+
from pysisyphus.optimizers.HessianOptimizer import HessianOptimizer, HessUpdate
|
|
13
|
+
from pysisyphus.optimizers.Optimizer import get_data_model, get_h5_group
|
|
14
|
+
|
|
15
|
+
from pysisyphus.helpers import array2string
|
|
16
|
+
import torch
|
|
17
|
+
|
|
18
|
+
class TSHessianOptimizer(HessianOptimizer):
|
|
19
|
+
"""Optimizer to find first-order saddle points."""
|
|
20
|
+
|
|
21
|
+
valid_updates = ("bofill", "ts_bfgs", "ts_bfgs_org", "ts_bfgs_rev")
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
geometry: Geometry,
|
|
26
|
+
roots: Optional[List[int]] = None,
|
|
27
|
+
root: int = 0,
|
|
28
|
+
hessian_ref: Optional[str] = None,
|
|
29
|
+
rx_modes=None,
|
|
30
|
+
prim_coord=None,
|
|
31
|
+
rx_coords=None,
|
|
32
|
+
hessian_init: HessInit = "calc",
|
|
33
|
+
hessian_update: HessUpdate = "bofill",
|
|
34
|
+
hessian_recalc_reset: bool = True,
|
|
35
|
+
max_micro_cycles: int = 50,
|
|
36
|
+
trust_radius: float = 0.3,
|
|
37
|
+
trust_max: float = 0.5,
|
|
38
|
+
augment_bonds: bool = False,
|
|
39
|
+
min_line_search: bool = False,
|
|
40
|
+
max_line_search: bool = False,
|
|
41
|
+
assert_neg_eigval: bool = False,
|
|
42
|
+
**kwargs,
|
|
43
|
+
) -> None:
|
|
44
|
+
"""Baseclass for transition state optimizers utilizing Hessian information.
|
|
45
|
+
|
|
46
|
+
Several arguments expect a typed primitive or an iterable of typed primitives.
|
|
47
|
+
A typed primitive is specified as (PrimType, int, int, ...), e.g., for a bond
|
|
48
|
+
between atoms 0 and 1: (BOND, 0, 1) or for a bend between the atom triple 0, 1, 2
|
|
49
|
+
as (BEND, 0, 1, 2).
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
geometry
|
|
54
|
+
Geometry to be optimized.
|
|
55
|
+
roots
|
|
56
|
+
Indices of modes to maximize along, e.g., to optimize saddle points of 2nd order.
|
|
57
|
+
Overrides 'root'.
|
|
58
|
+
root
|
|
59
|
+
Index of imaginary mode to maximize along. Shortcut for 'roots' with only one root.
|
|
60
|
+
hessian_ref
|
|
61
|
+
Filename pointing to a pysisyphus HDF5 Hessian.
|
|
62
|
+
rx_modes : iterable of (iterable of (typed_prim, phase_factor))
|
|
63
|
+
Select initial root(s) by overlap with a modes constructed from the given
|
|
64
|
+
typed primitives with respective phase factors.
|
|
65
|
+
prim_coord : typed_prim
|
|
66
|
+
Select initial root/imaginary mode by overlap with this internal coordinate.
|
|
67
|
+
Shortcut for 'rx_modes' with only one internal coordinate.
|
|
68
|
+
rx_coords : iterable of (typed_prim)
|
|
69
|
+
Construct imaginary mode comprising the given typed prims by modifying
|
|
70
|
+
a model Hessian.
|
|
71
|
+
hessian_init
|
|
72
|
+
Type of initial model Hessian.
|
|
73
|
+
hessian_update
|
|
74
|
+
Type of Hessian update. Defaults to BFGS for minimizations and Bofill
|
|
75
|
+
for saddle point searches.
|
|
76
|
+
hessian_recalc_reset
|
|
77
|
+
Whether to skip Hessian recalculation after reset. Undocumented.
|
|
78
|
+
max_micro_cycles
|
|
79
|
+
Maximum number of RS iterations.
|
|
80
|
+
trust_radius
|
|
81
|
+
Initial trust radius in whatever unit the optimization is carried out.
|
|
82
|
+
trust_max
|
|
83
|
+
Maximum trust radius.
|
|
84
|
+
augment_bonds
|
|
85
|
+
Try to derive additional streching coordinates from the imaginary mode.
|
|
86
|
+
min_line_search
|
|
87
|
+
Carry out line search along the imaginary mode.
|
|
88
|
+
max_line_search
|
|
89
|
+
Carry out line search in the subspace that is minimized.
|
|
90
|
+
assert_neg_eigval
|
|
91
|
+
Check for the existences for at least one significant negative eigenvalue.
|
|
92
|
+
If enabled and no negative eigenvalue is present the optimization will be
|
|
93
|
+
aborted.
|
|
94
|
+
|
|
95
|
+
Other Parameters
|
|
96
|
+
----------------
|
|
97
|
+
**kwargs
|
|
98
|
+
Keyword arguments passed to the HessianOptimizer/Optimizer baseclass.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
assert (
|
|
102
|
+
hessian_update in self.valid_updates
|
|
103
|
+
), f"Invalid Hessian update. Please chose from: {self.valid_updates}!"
|
|
104
|
+
|
|
105
|
+
super().__init__(
|
|
106
|
+
geometry,
|
|
107
|
+
hessian_init=hessian_init,
|
|
108
|
+
hessian_update=hessian_update,
|
|
109
|
+
trust_radius=trust_radius,
|
|
110
|
+
trust_max=trust_max,
|
|
111
|
+
hessian_recalc_reset=hessian_recalc_reset,
|
|
112
|
+
**kwargs,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
if (root is not None) and (roots is None):
|
|
116
|
+
roots = [
|
|
117
|
+
root,
|
|
118
|
+
]
|
|
119
|
+
elif roots is None:
|
|
120
|
+
roots = list()
|
|
121
|
+
self.roots = roots
|
|
122
|
+
self.log(f"{self.roots=}")
|
|
123
|
+
self.hessian_ref = hessian_ref
|
|
124
|
+
try:
|
|
125
|
+
with h5py.File(self.hessian_ref, "r") as handle:
|
|
126
|
+
self.hessian_ref = handle["hessian"][:]
|
|
127
|
+
_ = self.geometry.coords.size
|
|
128
|
+
expected_shape = (_, _)
|
|
129
|
+
shape = self.hessian_ref.shape
|
|
130
|
+
# Hessian is not yet converted to the correct coordinate system if
|
|
131
|
+
# coord_type != cart.
|
|
132
|
+
assert (
|
|
133
|
+
self.geometry.coord_type == "cart"
|
|
134
|
+
), "hessian_ref with internal coordinates are not yet supported."
|
|
135
|
+
assert shape == expected_shape, (
|
|
136
|
+
f"Shape of reference Hessian {shape} doesn't match the expected "
|
|
137
|
+
f"shape {expected_shape} of the Hessian for the current coordinates!"
|
|
138
|
+
)
|
|
139
|
+
except OSError as err:
|
|
140
|
+
self.log(
|
|
141
|
+
f"Tried to load reference Hessian from '{self.hessian_ref}' "
|
|
142
|
+
"but the file could not be found."
|
|
143
|
+
)
|
|
144
|
+
self.hessian_ref = None
|
|
145
|
+
except (ValueError, TypeError) as err:
|
|
146
|
+
self.log(f"No reference Hessian provided.")
|
|
147
|
+
|
|
148
|
+
# Select initial root according to highest contribution of 'prim_coord'
|
|
149
|
+
if prim_coord is not None:
|
|
150
|
+
self.log("'prim_coord' given. Overwriting/setting 'rx_modes'.")
|
|
151
|
+
rx_modes = [[[prim_coord, 1.0]]]
|
|
152
|
+
self.prim_coord = prim_coord
|
|
153
|
+
|
|
154
|
+
# Construct initial imaginary mode from the given inputs while respecting
|
|
155
|
+
# the given weight/phase factors.
|
|
156
|
+
self.rx_modes = rx_modes
|
|
157
|
+
|
|
158
|
+
# Construct initial imaginary mode according the primitive internals in
|
|
159
|
+
# 'rx_coords' by modifying a model Hessian.
|
|
160
|
+
if rx_coords is not None:
|
|
161
|
+
rx_coords = normalize_prim_inputs(rx_coords)
|
|
162
|
+
self.rx_coords = rx_coords
|
|
163
|
+
|
|
164
|
+
# Bond augmentation is only useful with calculated hessians
|
|
165
|
+
self.augment_bonds = augment_bonds and (self.hessian_init == "calc")
|
|
166
|
+
self.min_line_search = min_line_search
|
|
167
|
+
self.max_line_search = max_line_search
|
|
168
|
+
self.assert_neg_eigval = assert_neg_eigval
|
|
169
|
+
|
|
170
|
+
self.ts_modes = list()
|
|
171
|
+
self.max_micro_cycles = max_micro_cycles
|
|
172
|
+
self.prim_contrib_thresh = 0.05
|
|
173
|
+
|
|
174
|
+
self.alpha0 = 1
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def root(self):
|
|
178
|
+
return self.roots[0]
|
|
179
|
+
|
|
180
|
+
@root.setter
|
|
181
|
+
def root(self, root):
|
|
182
|
+
raise Exception("Setting 'self.root' is deprecated. Set 'self.roots' instead.")
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def roots(self):
|
|
186
|
+
return self._roots
|
|
187
|
+
|
|
188
|
+
@roots.setter
|
|
189
|
+
def roots(self, roots):
|
|
190
|
+
self._roots = np.array(roots, dtype=int)
|
|
191
|
+
|
|
192
|
+
def prepare_opt(self, *args, **kwargs):
|
|
193
|
+
if self.augment_bonds:
|
|
194
|
+
self.geometry = augment_bonds(self.geometry, root=self.root)
|
|
195
|
+
# Update data model and HD5 shapes, as the number of coordinates
|
|
196
|
+
# may have changed.
|
|
197
|
+
if self.dump:
|
|
198
|
+
self.data_model = get_data_model(
|
|
199
|
+
self.geometry, self.is_cos, self.max_cycles
|
|
200
|
+
)
|
|
201
|
+
# self.h5_group = get_h5_group(
|
|
202
|
+
# self.h5_fn, self.h5_group_name, self.data_model
|
|
203
|
+
# )
|
|
204
|
+
|
|
205
|
+
# Calculate/set initial hessian
|
|
206
|
+
super().prepare_opt(*args, **kwargs)
|
|
207
|
+
|
|
208
|
+
# Assume a guess hessian when not calculated. This hessian has to be
|
|
209
|
+
# modified according to the assumed reaction coordinates.
|
|
210
|
+
if self.hessian_init != "calc" and (self.rx_coords is not None):
|
|
211
|
+
assert self.geometry.coord_type != "cart", (
|
|
212
|
+
"Using a modified guess Hessian for TS-optimizations is "
|
|
213
|
+
"only supported in redundand internal coordinates "
|
|
214
|
+
"(coord_type=redund)"
|
|
215
|
+
)
|
|
216
|
+
prim_inds = [
|
|
217
|
+
self.geometry.internal.get_index_of_typed_prim(rxc)
|
|
218
|
+
for rxc in self.rx_coords
|
|
219
|
+
]
|
|
220
|
+
missing_prim_inds = [
|
|
221
|
+
self.rx_coords[i] for i, _ in enumerate(prim_inds) if _ is None
|
|
222
|
+
]
|
|
223
|
+
assert len(missing_prim_inds) == 0, (
|
|
224
|
+
"Some of the requested reaction coordinates are not defined: "
|
|
225
|
+
f"{missing_prim_inds}"
|
|
226
|
+
)
|
|
227
|
+
self.H = ts_hessian(self.H, coord_inds=prim_inds)
|
|
228
|
+
|
|
229
|
+
# Determiniation of initial mode either by using a provided
|
|
230
|
+
# reference hessian, or by using a supplied root.
|
|
231
|
+
|
|
232
|
+
if isinstance(self.H, torch.Tensor):
|
|
233
|
+
eigvals, eigvecs = torch.linalg.eigh(self.H)
|
|
234
|
+
eigvals = eigvals.cpu().numpy()
|
|
235
|
+
else:
|
|
236
|
+
eigvals, eigvecs = np.linalg.eigh(self.H)
|
|
237
|
+
neg_inds = eigvals < -self.small_eigval_thresh
|
|
238
|
+
self.log_negative_eigenvalues(eigvals, "Initial ")
|
|
239
|
+
|
|
240
|
+
self.log("Determining initial TS mode to follow uphill.")
|
|
241
|
+
# Select an initial TS-mode by highest overlap with eigenvectors from
|
|
242
|
+
# reference Hessian.
|
|
243
|
+
if self.hessian_ref is not None:
|
|
244
|
+
eigvals_ref, eigvecs_ref = np.linalg.eigh(self.hessian_ref)
|
|
245
|
+
self.log_negative_eigenvalues(eigvals_ref, "Reference ")
|
|
246
|
+
assert eigvals_ref[0] < -self.small_eigval_thresh
|
|
247
|
+
ref_mode = eigvecs_ref[:, 0]
|
|
248
|
+
overlaps = np.einsum("ij,j->i", eigvecs.T, ref_mode)
|
|
249
|
+
ovlp_str = array2string(overlaps, precision=4)
|
|
250
|
+
self.log(
|
|
251
|
+
"Overlaps between eigenvectors of current Hessian "
|
|
252
|
+
f"TS mode from reference Hessian:"
|
|
253
|
+
)
|
|
254
|
+
self.log(f"\t{ovlp_str}")
|
|
255
|
+
|
|
256
|
+
root = np.abs(overlaps).argmax()
|
|
257
|
+
self.roots = [
|
|
258
|
+
root,
|
|
259
|
+
]
|
|
260
|
+
print(
|
|
261
|
+
"Highest overlap between reference TS mode and "
|
|
262
|
+
f"eigenvector {self.root:02d}."
|
|
263
|
+
)
|
|
264
|
+
used_str = "overlap with reference TS mode"
|
|
265
|
+
# Construct an approximate initial mode according to user input
|
|
266
|
+
# and calculate overlaps with the current eigenvectors.
|
|
267
|
+
elif self.rx_modes is not None:
|
|
268
|
+
self.log(f"Constructing reference mode, according to user input")
|
|
269
|
+
assert self.geometry.coord_type != "cart"
|
|
270
|
+
int_ = self.geometry.internal
|
|
271
|
+
modes = list()
|
|
272
|
+
for i, rx_mode in enumerate(self.rx_modes):
|
|
273
|
+
mode = np.zeros_like(self.geometry.coords)
|
|
274
|
+
for typed_prim, val in rx_mode:
|
|
275
|
+
typed_prim = normalize_prim_input(typed_prim)[0]
|
|
276
|
+
ind = int_.get_index_of_typed_prim(typed_prim)
|
|
277
|
+
mode[ind] = val
|
|
278
|
+
self.log(
|
|
279
|
+
f"\tIndex {ind} (coordinate {typed_prim}) set to {val:.4f}"
|
|
280
|
+
)
|
|
281
|
+
mode /= np.linalg.norm(mode)
|
|
282
|
+
modes.append(mode)
|
|
283
|
+
mode_str = array2string(mode, precision=2)
|
|
284
|
+
self.log(f"Normalized reference mode {i:02d}: {mode_str}")
|
|
285
|
+
|
|
286
|
+
# Calculate overlaps in non-redundant subspace by zeroing overlaps
|
|
287
|
+
# in the redundant subspace.
|
|
288
|
+
small_inds = np.abs(eigvals) < self.small_eigval_thresh
|
|
289
|
+
# Take absolute value, because sign of eigenvectors is ambiguous.
|
|
290
|
+
ovlps = np.abs(np.einsum("ij,ki->kj", eigvecs, modes))
|
|
291
|
+
ovlps[:, small_inds] = 0.0
|
|
292
|
+
self.roots = ovlps.argmax(axis=1)
|
|
293
|
+
used_str = "overlap with user-generated mode"
|
|
294
|
+
else:
|
|
295
|
+
used_str = f"root(s)={self.roots}"
|
|
296
|
+
self.log(f"Used {used_str} to select inital TS mode.")
|
|
297
|
+
|
|
298
|
+
# Below, some code is found, that checks if the chosen root(s) are a
|
|
299
|
+
# sensible choice, i.e., if they are negative. Currently, it is commented out,
|
|
300
|
+
# as we can also start from the convex region of the PES.
|
|
301
|
+
#
|
|
302
|
+
# Check if the selected mode (root) is a sensible choice.
|
|
303
|
+
#
|
|
304
|
+
# small_eigval_thresh is positive and we dont take the absolute value
|
|
305
|
+
# of the eigenvalues. So we multiply small_eigval_thresh to get a
|
|
306
|
+
# negative number.
|
|
307
|
+
# assert (eigvals[self.roots] < -self.small_eigval_thresh).all(), (
|
|
308
|
+
# "Expected negative eigenvalue(s)! Eigenvalues of selected TS-modes "
|
|
309
|
+
# f"are above the the threshold of self.small_eigval_thresh:.6e}!"
|
|
310
|
+
# )
|
|
311
|
+
|
|
312
|
+
# Select an initial TS-mode by root index. self.root may have been
|
|
313
|
+
# modified by using a reference hessian.
|
|
314
|
+
self.ts_modes = eigvecs[:, self.roots].T
|
|
315
|
+
self.ts_mode_eigvals = eigvals[self.roots]
|
|
316
|
+
self.log(
|
|
317
|
+
f"Using root(s) {self.roots} with eigenvalues "
|
|
318
|
+
f"{array2string(self.ts_mode_eigvals, precision=6)} as TS mode.\n"
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
def update_ts_mode(self, eigvals, eigvecs):
|
|
322
|
+
neg_eigval_inds = eigvals < -self.small_eigval_thresh
|
|
323
|
+
neg_num = neg_eigval_inds.sum()
|
|
324
|
+
self.log_negative_eigenvalues(eigvals)
|
|
325
|
+
|
|
326
|
+
# When we left the convex region of the PES we only compare to other
|
|
327
|
+
# imaginary modes ... is this a bad idea? Maybe we should use all modes
|
|
328
|
+
# for the overlaps?!
|
|
329
|
+
if (self.ts_mode_eigvals < 0).all() and neg_num > 0:
|
|
330
|
+
infix = "imaginary "
|
|
331
|
+
ovlp_eigvecs = eigvecs[:, :neg_num]
|
|
332
|
+
eigvals = eigvals[:neg_num]
|
|
333
|
+
# When the eigenvalue corresponding to the TS mode has been negative once,
|
|
334
|
+
# we should not lose all negative eigenvalues. If this happens something went
|
|
335
|
+
# wrong and we crash :)
|
|
336
|
+
elif self.assert_neg_eigval and neg_num == 0:
|
|
337
|
+
raise AssertionError(
|
|
338
|
+
"Need at least 1 negative eigenvalue for TS optimization."
|
|
339
|
+
)
|
|
340
|
+
# Use all eigenvectors for overlaps when the eigenvalue corresponding to the TS
|
|
341
|
+
# mode is still positive.
|
|
342
|
+
else:
|
|
343
|
+
infix = ""
|
|
344
|
+
ovlp_eigvecs = eigvecs
|
|
345
|
+
|
|
346
|
+
if (
|
|
347
|
+
self.using_active_dofs
|
|
348
|
+
and self.ts_modes is not None
|
|
349
|
+
and self.ts_modes.shape[1] != ovlp_eigvecs.shape[0]
|
|
350
|
+
):
|
|
351
|
+
self.log("Projecting previous TS mode(s) onto active DOFs.")
|
|
352
|
+
if isinstance(self.ts_modes, torch.Tensor):
|
|
353
|
+
self.ts_modes = torch.stack(
|
|
354
|
+
[self.active_from_full(mode) for mode in self.ts_modes]
|
|
355
|
+
)
|
|
356
|
+
else:
|
|
357
|
+
self.ts_modes = np.stack(
|
|
358
|
+
[self.active_from_full(mode) for mode in self.ts_modes]
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
# Select new TS mode according to biggest overlap with previous TS mode.
|
|
362
|
+
self.log(f"Overlaps of previous TS mode with current {infix}mode(s):")
|
|
363
|
+
if isinstance(eigvecs, torch.Tensor):
|
|
364
|
+
ovlps = torch.abs(torch.einsum("ij,ki->kj", ovlp_eigvecs, self.ts_modes))
|
|
365
|
+
ovlps = ovlps.cpu().numpy()
|
|
366
|
+
else:
|
|
367
|
+
ovlps = np.abs(np.einsum("ij,ki->kj", ovlp_eigvecs, self.ts_modes))
|
|
368
|
+
for i, ovlp in enumerate(ovlps):
|
|
369
|
+
self.log(f"\tTS mode {i:02d}: {array2string(ovlp, precision=3)}")
|
|
370
|
+
max_ovlp_inds = np.argmax(ovlps, axis=1)
|
|
371
|
+
for i, _ in enumerate(self.ts_modes):
|
|
372
|
+
max_ovlp_ind = max_ovlp_inds[i].argmax()
|
|
373
|
+
self.log(
|
|
374
|
+
f"Mode {i}: highest overlap: {ovlps[i, max_ovlp_ind]:.6f} with mode "
|
|
375
|
+
f"{max_ovlp_ind}"
|
|
376
|
+
)
|
|
377
|
+
self.roots = max_ovlp_inds
|
|
378
|
+
self.ts_modes = ovlp_eigvecs.T[self.roots]
|
|
379
|
+
self.ts_mode_eigvals = eigvals[self.roots]
|
|
380
|
+
|
|
381
|
+
@staticmethod
|
|
382
|
+
def do_line_search(e0, e1, g0, g1, prev_step, maximize, logger=None):
|
|
383
|
+
poly_fit_kwargs = {
|
|
384
|
+
"e0": e0,
|
|
385
|
+
"e1": e1,
|
|
386
|
+
"g0": g0,
|
|
387
|
+
"g1": g1,
|
|
388
|
+
"maximize": maximize,
|
|
389
|
+
}
|
|
390
|
+
if not maximize:
|
|
391
|
+
poly_fit_kwargs.update(
|
|
392
|
+
{
|
|
393
|
+
"g0": prev_step.dot(g0),
|
|
394
|
+
"g1": prev_step.dot(g1),
|
|
395
|
+
}
|
|
396
|
+
)
|
|
397
|
+
prefix = "Max" if maximize else "Min"
|
|
398
|
+
|
|
399
|
+
fit_result = poly_fit.quartic_fit(**poly_fit_kwargs)
|
|
400
|
+
fit_energy = None
|
|
401
|
+
fit_grad = None
|
|
402
|
+
fit_step = None
|
|
403
|
+
if fit_result and (0.0 < fit_result.x <= 2.0):
|
|
404
|
+
x = fit_result.x
|
|
405
|
+
log(logger, f"{prefix}-subpsace interpolation succeeded: x={x:.6f}")
|
|
406
|
+
fit_energy = fit_result.y
|
|
407
|
+
fit_step = (1 - x) * -prev_step
|
|
408
|
+
fit_grad = (1 - x) * g0 + x * g1
|
|
409
|
+
return fit_energy, fit_grad, fit_step
|
|
410
|
+
|
|
411
|
+
def step_and_grad_from_line_search(
|
|
412
|
+
self,
|
|
413
|
+
energy,
|
|
414
|
+
gradient_trans,
|
|
415
|
+
eigvecs,
|
|
416
|
+
min_indices,
|
|
417
|
+
max_indices,
|
|
418
|
+
):
|
|
419
|
+
ip_step = np.zeros_like(gradient_trans)
|
|
420
|
+
ip_gradient_trans = gradient_trans.copy()
|
|
421
|
+
|
|
422
|
+
if self.max_line_search and self.cur_cycle > 0:
|
|
423
|
+
prev_energy = self.energies[-2]
|
|
424
|
+
prev_gradient = -self.forces[-2]
|
|
425
|
+
try:
|
|
426
|
+
prev_gradient_trans = eigvecs.T.dot(prev_gradient)
|
|
427
|
+
prev_step = self.steps[-1]
|
|
428
|
+
prev_step_trans = eigvecs.T.dot(prev_step)
|
|
429
|
+
# Will be raised when coordinates were rebuilt and the array shapes differe.
|
|
430
|
+
except ValueError:
|
|
431
|
+
return ip_step, ip_gradient_trans
|
|
432
|
+
|
|
433
|
+
# Max subspace
|
|
434
|
+
# max_energy, max_gradient, max_step = self.do_max_line_search(
|
|
435
|
+
max_energy, max_gradient, max_step = self.do_line_search(
|
|
436
|
+
prev_energy,
|
|
437
|
+
energy,
|
|
438
|
+
prev_gradient_trans[max_indices],
|
|
439
|
+
gradient_trans[max_indices],
|
|
440
|
+
prev_step=prev_step_trans[max_indices],
|
|
441
|
+
maximize=True,
|
|
442
|
+
logger=self.logger,
|
|
443
|
+
)
|
|
444
|
+
if max_gradient is not None:
|
|
445
|
+
ip_gradient_trans[max_indices] = max_gradient
|
|
446
|
+
ip_step[max_indices] = max_step
|
|
447
|
+
|
|
448
|
+
if self.min_line_search and self.cur_cycle > 0:
|
|
449
|
+
# Min subspace
|
|
450
|
+
# min_energy, min_gradient, min_step = self.do_min_line_search(
|
|
451
|
+
min_energy, min_gradient, min_step = self.do_line_search(
|
|
452
|
+
prev_energy,
|
|
453
|
+
energy,
|
|
454
|
+
prev_gradient_trans[min_indices],
|
|
455
|
+
gradient_trans[min_indices],
|
|
456
|
+
prev_step=prev_step_trans[min_indices],
|
|
457
|
+
maximize=False,
|
|
458
|
+
logger=self.logger,
|
|
459
|
+
)
|
|
460
|
+
if min_gradient is not None:
|
|
461
|
+
ip_gradient_trans[min_indices] = min_gradient
|
|
462
|
+
ip_step[min_indices] = min_step
|
|
463
|
+
return ip_step, ip_gradient_trans
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from pysisyphus.tsoptimizers.RSPRFOptimizer import RSPRFOptimizer
|
|
4
|
+
from pysisyphus.tsoptimizers.TRIM import TRIM
|
|
5
|
+
from pysisyphus.tsoptimizers.RSIRFOptimizer import RSIRFOptimizer
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"RSPRFOptimizer",
|
|
9
|
+
"TRIM",
|
|
10
|
+
"RSIRFOptimizer",
|
|
11
|
+
"TSHessianOptimizer",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger("tsoptimizer")
|
|
16
|
+
logger.setLevel(logging.DEBUG)
|
|
17
|
+
# delay = True prevents creation of empty logfiles
|
|
18
|
+
handler = logging.FileHandler("tsoptimizer.log", mode="w", delay=True)
|
|
19
|
+
# fmt_str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
20
|
+
fmt_str = "%(message)s"
|
|
21
|
+
formatter = logging.Formatter(fmt_str)
|
|
22
|
+
handler.setFormatter(formatter)
|
|
23
|
+
logger.addHandler(handler)
|