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,248 @@
|
|
|
1
|
+
# [1] https://aip.scitation.org/doi/pdf/10.1063/1.4905665?class=pdf
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pysisyphus.optimizers.Optimizer import Optimizer
|
|
6
|
+
from pysisyphus.intcoords.setup import get_bond_mat
|
|
7
|
+
from pysisyphus.optimizers.restrict_step import scale_by_max_step
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class StabilizedQNMethod(Optimizer):
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
geometry,
|
|
14
|
+
alpha=0.5,
|
|
15
|
+
alpha_max=1,
|
|
16
|
+
alpha_stretch=0.5,
|
|
17
|
+
alpha_stretch_max=1,
|
|
18
|
+
eps=1e-4,
|
|
19
|
+
hist_max=10,
|
|
20
|
+
E_thresh=1e-6,
|
|
21
|
+
bio=True,
|
|
22
|
+
trust_radius=0.1,
|
|
23
|
+
linesearch=True,
|
|
24
|
+
**kwargs,
|
|
25
|
+
):
|
|
26
|
+
super().__init__(geometry, **kwargs)
|
|
27
|
+
|
|
28
|
+
self.alpha = alpha
|
|
29
|
+
self.alpha_max = alpha_max
|
|
30
|
+
self.alpha_stretch = alpha_stretch
|
|
31
|
+
self.alpha_stretch_max = alpha_stretch_max
|
|
32
|
+
self.eps = eps
|
|
33
|
+
self.hist_max = int(hist_max)
|
|
34
|
+
self.E_thresh = E_thresh
|
|
35
|
+
self.bio = bio
|
|
36
|
+
self.trust_radius = trust_radius
|
|
37
|
+
self.linesearch = linesearch
|
|
38
|
+
|
|
39
|
+
self.log(
|
|
40
|
+
f"Keeping at most information from {self.hist_max} " "previous cycles."
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
self.alpha_start = self.alpha
|
|
44
|
+
self.alpha_stretch_start = self.alpha_stretch
|
|
45
|
+
|
|
46
|
+
self.gradients_for_precon = list()
|
|
47
|
+
self.coords_for_precon = list()
|
|
48
|
+
self.stretch_proj_signs = list()
|
|
49
|
+
|
|
50
|
+
def prepare_opt(self):
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def n_hist(self):
|
|
55
|
+
return len(self.steps_normed)
|
|
56
|
+
|
|
57
|
+
def bio_mode(self, gradient):
|
|
58
|
+
bond_mat = get_bond_mat(self.geometry)
|
|
59
|
+
atom_num = len(self.geometry.atoms)
|
|
60
|
+
bond_vec_empty = np.zeros((atom_num, 3))
|
|
61
|
+
c3d = self.geometry.coords3d
|
|
62
|
+
bond_vectors = list()
|
|
63
|
+
unique_bonds = set(
|
|
64
|
+
[(min(m, k), max(m, k)) for m, k in zip(*np.where(bond_mat == True))]
|
|
65
|
+
)
|
|
66
|
+
for m, k in unique_bonds:
|
|
67
|
+
bm = bond_vec_empty.copy()
|
|
68
|
+
bm[k] = c3d[k] - c3d[m]
|
|
69
|
+
bm[m] = -bm[k]
|
|
70
|
+
bond_vectors.append(bm)
|
|
71
|
+
# The 3d array is reshaped to 2d, so its last dimension matches
|
|
72
|
+
# the gradient's dimension. LHS and RHS are accessible by simple
|
|
73
|
+
# dot products (see [1] (27)).
|
|
74
|
+
bond_vectors = np.array(bond_vectors).reshape(-1, gradient.size)
|
|
75
|
+
lhs = bond_vectors.dot(gradient)
|
|
76
|
+
self.stretch_proj_signs.append(np.sign(lhs).astype(int))
|
|
77
|
+
# Bond-vector overlap matrix.
|
|
78
|
+
rhs = bond_vectors.dot(bond_vectors.T)
|
|
79
|
+
coeffs = np.linalg.solve(rhs, lhs)
|
|
80
|
+
stretch_gradient = np.einsum("i,ij->j", coeffs, bond_vectors)
|
|
81
|
+
remainder_gradient = gradient - stretch_gradient
|
|
82
|
+
return stretch_gradient, remainder_gradient
|
|
83
|
+
|
|
84
|
+
def adjust_alpha_stretch(self):
|
|
85
|
+
try:
|
|
86
|
+
# -1 when signs changed, 1 when sign is constant
|
|
87
|
+
mult = self.stretch_proj_signs[-1] * self.stretch_proj_signs[-2]
|
|
88
|
+
except IndexError:
|
|
89
|
+
self.log("Can't update alpha_stretch yet!")
|
|
90
|
+
return
|
|
91
|
+
except ValueError:
|
|
92
|
+
self.log(
|
|
93
|
+
"Number of bonds found changed between cycles! Skipping "
|
|
94
|
+
"adjustment of alpha_stretch."
|
|
95
|
+
)
|
|
96
|
+
return
|
|
97
|
+
constant_signs = np.sum(mult == 1)
|
|
98
|
+
fraction = constant_signs / mult.size
|
|
99
|
+
if fraction >= (2 / 3):
|
|
100
|
+
self.alpha_stretch = min(self.alpha_stretch_max, 1.1 * self.alpha_stretch)
|
|
101
|
+
msg = "Increased"
|
|
102
|
+
else:
|
|
103
|
+
self.alpha_stretch *= 1 / 1.1
|
|
104
|
+
msg = "Decreased"
|
|
105
|
+
self.log(f"{msg} alpha_stretch to {self.alpha_stretch:.6f}")
|
|
106
|
+
|
|
107
|
+
def adjust_alpha(self, gradient, precon_gradient):
|
|
108
|
+
# Overlap between full and preconditioned gradient.
|
|
109
|
+
grad_ovlp = (
|
|
110
|
+
gradient.dot(precon_gradient)
|
|
111
|
+
/ np.linalg.norm(gradient)
|
|
112
|
+
/ np.linalg.norm(precon_gradient)
|
|
113
|
+
)
|
|
114
|
+
if grad_ovlp > 0.2:
|
|
115
|
+
self.alpha = min(self.alpha_max, 1.1 * self.alpha)
|
|
116
|
+
else:
|
|
117
|
+
self.alpha *= 0.85
|
|
118
|
+
self.log(
|
|
119
|
+
"Overlap between full gradient and preconditioned gradient "
|
|
120
|
+
f"is {grad_ovlp:.4f}. New alpha={self.alpha:.4f}."
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
def precondition_gradient(self, gradient, steps, grad_diffs, eps):
|
|
124
|
+
# Construct overlap matrix S between normalized steps
|
|
125
|
+
#
|
|
126
|
+
step_norms = np.linalg.norm(steps, axis=1)
|
|
127
|
+
steps_normed = steps / step_norms[:, None]
|
|
128
|
+
S = np.einsum("ij,jk->ik", steps_normed, steps_normed.T)
|
|
129
|
+
# Determine significant subspace by checking the eigenvalues of
|
|
130
|
+
# the overlap matrix.
|
|
131
|
+
w, v = np.linalg.eigh(S)
|
|
132
|
+
# Significant subspace indices
|
|
133
|
+
significant = (w / w.max()) > eps
|
|
134
|
+
ndim = np.sum(significant)
|
|
135
|
+
self.log(f"ndim = {ndim}")
|
|
136
|
+
# Continue only with eigenvalues and -vectors in the significant
|
|
137
|
+
# subspace.
|
|
138
|
+
eigvals = w[significant]
|
|
139
|
+
eigvecs = v[:, significant]
|
|
140
|
+
|
|
141
|
+
# Transform steps and gradient differences to significant subspace
|
|
142
|
+
norm_fac = 1 / eigvals ** (1 / 2)
|
|
143
|
+
# Eq. (8) in [1]
|
|
144
|
+
steps_normed_sub = norm_fac * np.einsum("ki,kj->ji", eigvecs, steps_normed)
|
|
145
|
+
|
|
146
|
+
# Eq. (11) in [1]
|
|
147
|
+
eigvecs_weighted = eigvecs / np.array(step_norms)[:, None]
|
|
148
|
+
grad_diffs_sub = norm_fac * np.einsum("ki,kj->ji", eigvecs_weighted, grad_diffs)
|
|
149
|
+
|
|
150
|
+
# Assemble approximate hessian
|
|
151
|
+
hess_approx = np.einsum("ij,ik->jk", grad_diffs_sub, steps_normed_sub)
|
|
152
|
+
hess_approx = (hess_approx + hess_approx.T) / 2
|
|
153
|
+
hess_w, hess_v = np.linalg.eigh(hess_approx)
|
|
154
|
+
|
|
155
|
+
# Calculate step directions and gradient difference in the original
|
|
156
|
+
# space. Eq. (15)
|
|
157
|
+
proj_v = np.einsum("ki,jk->ji", hess_v, steps_normed_sub)
|
|
158
|
+
proj_dg = np.einsum("ki,jk->ji", hess_v, grad_diffs_sub)
|
|
159
|
+
|
|
160
|
+
residuals = np.linalg.norm(proj_dg - hess_w * proj_v, axis=0)
|
|
161
|
+
eigvals_mod = np.sqrt(hess_w ** 2 + residuals ** 2)
|
|
162
|
+
|
|
163
|
+
# precon_grad = np.einsum("i,j,ij,ij->i", cur_grad, 1/eigvals_mod, proj_v, proj_v)
|
|
164
|
+
precon_grad = np.einsum(
|
|
165
|
+
"i,j,ij,ij->i", gradient, 1 / eigvals_mod, proj_v, proj_v
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
projector = proj_v.dot(proj_v.T)
|
|
169
|
+
perp_projector = np.eye(gradient.size) - projector
|
|
170
|
+
perp_grad = perp_projector.dot(gradient)
|
|
171
|
+
# Alternative formulation
|
|
172
|
+
# perp_grad_ = gradient - (proj_v.T.dot(gradient) * proj_v).sum(axis=1)
|
|
173
|
+
# np.testing.assert_allclose(perp_grad_, perp_grad, atol=1e-16)
|
|
174
|
+
|
|
175
|
+
self.adjust_alpha(gradient, precon_grad)
|
|
176
|
+
tot_precon_gradient = precon_grad + self.alpha * perp_grad
|
|
177
|
+
return tot_precon_gradient
|
|
178
|
+
|
|
179
|
+
def optimize(self):
|
|
180
|
+
gradient = self.geometry.gradient
|
|
181
|
+
energy = self.geometry.energy
|
|
182
|
+
self.forces.append(-gradient)
|
|
183
|
+
self.energies.append(energy)
|
|
184
|
+
self.log(f"norm(forces)={np.linalg.norm(gradient):.4e}")
|
|
185
|
+
|
|
186
|
+
if self.bio:
|
|
187
|
+
stretch_gradient, remainder_gradient = self.bio_mode(gradient)
|
|
188
|
+
self.adjust_alpha_stretch()
|
|
189
|
+
# Steepest descent against the stretch_gradient
|
|
190
|
+
stretch_step = -self.alpha_stretch * stretch_gradient
|
|
191
|
+
new_coords = self.geometry.coords + stretch_step
|
|
192
|
+
self.geometry.coords = new_coords
|
|
193
|
+
# Use only the remaining gradient for the rest of this method
|
|
194
|
+
gradient = remainder_gradient
|
|
195
|
+
|
|
196
|
+
self.gradients_for_precon.append(gradient)
|
|
197
|
+
self.coords_for_precon.append(self.geometry.coords.copy())
|
|
198
|
+
|
|
199
|
+
if len(self.coords_for_precon) > 2:
|
|
200
|
+
steps = np.diff(self.coords_for_precon, axis=0)[-self.hist_max :]
|
|
201
|
+
grad_diffs = np.diff(self.gradients_for_precon, axis=0)[-self.hist_max :]
|
|
202
|
+
|
|
203
|
+
self.log(
|
|
204
|
+
"Preconditioning gradient with information from "
|
|
205
|
+
f"{len(steps)+1} previous cycles."
|
|
206
|
+
)
|
|
207
|
+
precon_grad = self.precondition_gradient(
|
|
208
|
+
gradient, steps, grad_diffs, self.eps
|
|
209
|
+
)
|
|
210
|
+
step = -precon_grad
|
|
211
|
+
else:
|
|
212
|
+
self.log("Took pure steepest descent step.")
|
|
213
|
+
step = self.alpha * -gradient
|
|
214
|
+
scale_by_max_step(step, self.trust_radius)
|
|
215
|
+
|
|
216
|
+
if self.linesearch:
|
|
217
|
+
# Calculate energy at new geometry
|
|
218
|
+
new_coords = self.geometry.coords + step
|
|
219
|
+
_ = self.geometry.get_energy_and_forces_at(new_coords)
|
|
220
|
+
new_energy = _["energy"]
|
|
221
|
+
delta_energy = new_energy - energy
|
|
222
|
+
self.log(
|
|
223
|
+
f"Current energy is {energy:.6f} au. New energy is "
|
|
224
|
+
f"{new_energy:.6f} au, ΔE={delta_energy:.6f} au."
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
energy_rise_too_big = new_energy > (energy + self.E_thresh)
|
|
228
|
+
alpha_still_big_enough = self.alpha > (self.alpha_start / 10)
|
|
229
|
+
alpha_stre_still_big_enough = self.alpha_stretch > (
|
|
230
|
+
self.alpha_stretch_start / 10
|
|
231
|
+
)
|
|
232
|
+
if (
|
|
233
|
+
energy_rise_too_big
|
|
234
|
+
and alpha_still_big_enough
|
|
235
|
+
and alpha_stre_still_big_enough
|
|
236
|
+
):
|
|
237
|
+
self.log(f"Energy increased by {delta_energy:.6f} au")
|
|
238
|
+
self.gradients_for_precon = self.gradients_for_precon[-2:-1]
|
|
239
|
+
self.coords_for_precon = self.coords_for_precon[-2:-1]
|
|
240
|
+
self.log("Resetted history.")
|
|
241
|
+
self.alpha /= 2
|
|
242
|
+
self.alpha_stretch /= 2
|
|
243
|
+
|
|
244
|
+
self.log(f"Decreased alpha to {self.alpha}")
|
|
245
|
+
self.log("Reverting bad step")
|
|
246
|
+
return None
|
|
247
|
+
|
|
248
|
+
return step
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from pysisyphus.optimizers.BacktrackingOptimizer import BacktrackingOptimizer
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SteepestDescent(BacktrackingOptimizer):
|
|
5
|
+
def __init__(self, geometry, alpha=0.1, **kwargs):
|
|
6
|
+
super().__init__(geometry, alpha=alpha, **kwargs)
|
|
7
|
+
|
|
8
|
+
def prepare_opt(self):
|
|
9
|
+
self.log("no backtracking in cycle 0")
|
|
10
|
+
|
|
11
|
+
def optimize(self):
|
|
12
|
+
if self.is_cos and self.align:
|
|
13
|
+
self.procrustes()
|
|
14
|
+
|
|
15
|
+
self.forces.append(self.geometry.forces)
|
|
16
|
+
self.energies.append(self.geometry.energy)
|
|
17
|
+
|
|
18
|
+
if self.cur_cycle > 0:
|
|
19
|
+
self.skip = self.backtrack(self.forces[-1], self.forces[-2])
|
|
20
|
+
|
|
21
|
+
step = self.alpha * self.forces[-1]
|
|
22
|
+
step = self.scale_by_max_step(step)
|
|
23
|
+
return step
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# [1] https://aip.scitation.org/doi/abs/10.1063/1.3664901
|
|
2
|
+
# Behn, 2011, Freezing string method
|
|
3
|
+
# [2] https://aip.scitation.org/doi/pdf/10.1063/1.4804162
|
|
4
|
+
# Zimmerman, 2013, Growing string with interpolation and optimization
|
|
5
|
+
# in internal coordiantes
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from pysisyphus.optimizers.hessian_updates import double_damp
|
|
10
|
+
from pysisyphus.optimizers.closures import bfgs_multiply
|
|
11
|
+
from pysisyphus.optimizers.Optimizer import Optimizer
|
|
12
|
+
from pysisyphus.optimizers.restrict_step import scale_by_max_step
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class StringOptimizer(Optimizer):
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
geometry,
|
|
19
|
+
max_step=0.1,
|
|
20
|
+
stop_in_when_full=-1,
|
|
21
|
+
keep_last=10,
|
|
22
|
+
lbfgs_when_full=True,
|
|
23
|
+
gamma_mult=False,
|
|
24
|
+
double_damp=True,
|
|
25
|
+
scale_step="global",
|
|
26
|
+
**kwargs,
|
|
27
|
+
):
|
|
28
|
+
super().__init__(geometry, max_step=max_step, **kwargs)
|
|
29
|
+
|
|
30
|
+
assert (
|
|
31
|
+
self.is_cos
|
|
32
|
+
), "StringOptimizer is only intended to be used with COS objects."
|
|
33
|
+
|
|
34
|
+
self.stop_in_when_full = int(stop_in_when_full)
|
|
35
|
+
self.keep_last = int(keep_last)
|
|
36
|
+
assert self.keep_last >= 0
|
|
37
|
+
self.lbfgs_when_full = lbfgs_when_full
|
|
38
|
+
if self.lbfgs_when_full and (self.keep_last == 0):
|
|
39
|
+
print("lbfgs_when_full is True, but keep_last is 0!")
|
|
40
|
+
self.gamma_mult = bool(gamma_mult)
|
|
41
|
+
self.double_damp = bool(double_damp)
|
|
42
|
+
self.scale_step = scale_step
|
|
43
|
+
assert self.scale_step in ("global", "per_image")
|
|
44
|
+
|
|
45
|
+
# Add one as we later subtract 1 before we check if this value is 0.
|
|
46
|
+
self.stop_in = self.stop_in_when_full + 1
|
|
47
|
+
self.is_cart_opt = self.geometry.coord_type == "cart"
|
|
48
|
+
self.s_list = list()
|
|
49
|
+
self.y_list = list()
|
|
50
|
+
self.inds = list()
|
|
51
|
+
|
|
52
|
+
def prepare_opt(self):
|
|
53
|
+
if self.align and self.is_cart_opt:
|
|
54
|
+
self.procrustes()
|
|
55
|
+
|
|
56
|
+
def reset(self):
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
def restrict_step_components(self, steps):
|
|
60
|
+
too_big = np.abs(steps) > self.max_step
|
|
61
|
+
self.log(f"Found {np.sum(too_big)} big step components.")
|
|
62
|
+
signs = np.sign(steps[too_big])
|
|
63
|
+
steps[too_big] = signs * self.max_step
|
|
64
|
+
return steps
|
|
65
|
+
|
|
66
|
+
def check_convergence(self, *args, **kwargs):
|
|
67
|
+
# Normal convergence check with gradients etc.
|
|
68
|
+
converged, conv_info = super().check_convergence(*args, **kwargs)
|
|
69
|
+
|
|
70
|
+
if self.geometry.fully_grown:
|
|
71
|
+
# We only start decrementing the counter after the string is fully grown.
|
|
72
|
+
self.stop_in -= 1
|
|
73
|
+
# Don't print this message if stop_in was disabled in the first place (< 0).
|
|
74
|
+
if self.stop_in >= 0:
|
|
75
|
+
self.log(f"String is fully grown. Stopping in {self.stop_in} cycle(s).")
|
|
76
|
+
|
|
77
|
+
fully_grown = self.geometry.fully_grown
|
|
78
|
+
full_stop = fully_grown and (self.stop_in == 0)
|
|
79
|
+
# full_stop will take precedence when True.
|
|
80
|
+
return full_stop or (fully_grown and converged), conv_info
|
|
81
|
+
|
|
82
|
+
def optimize(self):
|
|
83
|
+
new_image_inds = self.geometry.new_image_inds
|
|
84
|
+
string_size_changed = len(new_image_inds) > 0
|
|
85
|
+
|
|
86
|
+
if self.align and string_size_changed and self.is_cart_opt:
|
|
87
|
+
self.procrustes()
|
|
88
|
+
self.log("Aligned string.")
|
|
89
|
+
|
|
90
|
+
forces = self.geometry.forces
|
|
91
|
+
self.energies.append(self.geometry.energy)
|
|
92
|
+
self.forces.append(forces)
|
|
93
|
+
|
|
94
|
+
cur_size = self.geometry.string_size
|
|
95
|
+
add_to_list = (
|
|
96
|
+
self.keep_last > 0 # Only add to s_list and y_list if we want to keep
|
|
97
|
+
and self.cur_cycle
|
|
98
|
+
> 0 # cycles and if we can actually calculate differences.
|
|
99
|
+
and (
|
|
100
|
+
not self.lbfgs_when_full # Add when LBFGS is allowed before fully grown.
|
|
101
|
+
or self.lbfgs_when_full
|
|
102
|
+
and self.geometry.fully_grown
|
|
103
|
+
and not string_size_changed # Don't add when string has to be fully grown
|
|
104
|
+
# but grew fully in this cycle.
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
if add_to_list:
|
|
108
|
+
inds = list(range(cur_size))
|
|
109
|
+
try:
|
|
110
|
+
y = self.forces[-2] - forces
|
|
111
|
+
s = self.coords[-1] - self.coords[-2]
|
|
112
|
+
# Will be raised when the string grew in the previous cycle.
|
|
113
|
+
except ValueError:
|
|
114
|
+
cur_forces = np.delete(
|
|
115
|
+
forces.reshape(cur_size, -1), new_image_inds, axis=0
|
|
116
|
+
).flatten()
|
|
117
|
+
y = self.forces[-2] - cur_forces
|
|
118
|
+
cur_coords = np.delete(
|
|
119
|
+
self.coords[-1].reshape(cur_size, -1), new_image_inds, axis=0
|
|
120
|
+
).flatten()
|
|
121
|
+
s = self.coords[-2] - cur_coords
|
|
122
|
+
inds = np.delete(inds, new_image_inds)
|
|
123
|
+
|
|
124
|
+
if self.double_damp:
|
|
125
|
+
s, y = double_damp(s, y, s_list=self.s_list, y_list=self.y_list)
|
|
126
|
+
|
|
127
|
+
self.s_list.append(s)
|
|
128
|
+
self.y_list.append(y)
|
|
129
|
+
self.inds.append(inds)
|
|
130
|
+
# Drop oldest vectors
|
|
131
|
+
self.s_list = self.s_list[-self.keep_last :]
|
|
132
|
+
self.y_list = self.y_list[-self.keep_last :]
|
|
133
|
+
self.inds = self.inds[-self.keep_last :]
|
|
134
|
+
|
|
135
|
+
# Results in steepest descent step for empty s_list & y_list
|
|
136
|
+
step = bfgs_multiply(
|
|
137
|
+
self.s_list,
|
|
138
|
+
self.y_list,
|
|
139
|
+
forces,
|
|
140
|
+
gamma_mult=self.gamma_mult,
|
|
141
|
+
inds=self.inds,
|
|
142
|
+
cur_size=cur_size,
|
|
143
|
+
logger=self.logger,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# When LBFGS is not yet enabled then s_list and y_list will
|
|
147
|
+
# be empty and the step from bfgs_multiply will be a simple SD step.
|
|
148
|
+
# We try to calculated an improved step it via conjugate gradient.
|
|
149
|
+
previous_step_with_same_size = (self.cur_cycle > 0) and (
|
|
150
|
+
not string_size_changed
|
|
151
|
+
)
|
|
152
|
+
lbfgs_lists_empty = (len(self.s_list) == 0) and (len(self.y_list) == 0)
|
|
153
|
+
if previous_step_with_same_size and lbfgs_lists_empty:
|
|
154
|
+
prev_forces = self.forces[-2]
|
|
155
|
+
# Fletcher-Reeves
|
|
156
|
+
kind = "Fletcher-Reeves"
|
|
157
|
+
beta = forces.dot(forces) / prev_forces.dot(prev_forces)
|
|
158
|
+
# Polak-Ribiere
|
|
159
|
+
# kind = "Polak-Ribiere"
|
|
160
|
+
# beta = forces.dot(forces - prev_forces) / prev_forces.dot(prev_forces)
|
|
161
|
+
beta = min(beta, 1)
|
|
162
|
+
step = forces + beta * self.steps[-1]
|
|
163
|
+
self.log(f"{kind} conjugate gradient correction, β={beta:.6f}")
|
|
164
|
+
|
|
165
|
+
if self.scale_step == "global":
|
|
166
|
+
step = scale_by_max_step(step, self.max_step)
|
|
167
|
+
elif self.scale_step == "per_image":
|
|
168
|
+
for image_step in step.reshape(len(self.geometry.images), -1):
|
|
169
|
+
scale_by_max_step(image_step, self.max_step)
|
|
170
|
+
else:
|
|
171
|
+
raise Exception("Invalid scale_step={self.scale_step}!")
|
|
172
|
+
|
|
173
|
+
return step
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
__all__ = [
|
|
4
|
+
"BFGS",
|
|
5
|
+
"ConjugateGradient",
|
|
6
|
+
"CubicNewton",
|
|
7
|
+
"FIRE",
|
|
8
|
+
"LayerOpt",
|
|
9
|
+
"LBFGS",
|
|
10
|
+
"MicroOptimizer",
|
|
11
|
+
"NCOptimizer",
|
|
12
|
+
"PreconLBFGS",
|
|
13
|
+
"PreconSteepestDescent",
|
|
14
|
+
"QuickMin",
|
|
15
|
+
"RFOptimizer",
|
|
16
|
+
"SteepestDescent",
|
|
17
|
+
"StringOptimizer",
|
|
18
|
+
"StabilizedQNMethod",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
from pysisyphus.optimizers.CubicNewton import CubicNewton
|
|
22
|
+
from pysisyphus.optimizers.MicroOptimizer import MicroOptimizer
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger("optimizer")
|
|
25
|
+
logger.setLevel(logging.DEBUG)
|
|
26
|
+
# delay = True prevents creation of empty logfiles
|
|
27
|
+
handler = logging.FileHandler("optimizer.log", mode="w", delay=True)
|
|
28
|
+
# fmt_str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
29
|
+
fmt_str = "%(message)s"
|
|
30
|
+
formatter = logging.Formatter(fmt_str)
|
|
31
|
+
handler.setFormatter(formatter)
|
|
32
|
+
logger.addHandler(handler)
|
|
33
|
+
|
|
34
|
+
# logger = logging.getLogger("gdiis")
|
|
35
|
+
# logger.setLevel(logging.DEBUG)
|
|
36
|
+
# # delay = True prevents creation of empty logfiles
|
|
37
|
+
# handler = logging.FileHandler("gdiis.log", mode="w", delay=True)
|
|
38
|
+
# fmt_str = "%(message)s"
|
|
39
|
+
# formatter = logging.Formatter(fmt_str)
|
|
40
|
+
# handler.setFormatter(formatter)
|
|
41
|
+
# logger.addHandler(handler)
|