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,169 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import shutil
|
|
5
|
+
from subprocess import PIPE, Popen
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from pysisyphus.config import get_cmd
|
|
10
|
+
from pysisyphus.constants import AU2EV
|
|
11
|
+
from pysisyphus.wrapper.exceptions import SegfaultException
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger("mwfn")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def log(msg):
|
|
18
|
+
logger.debug(msg)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def wrap_stdin(stdin):
|
|
22
|
+
return f"<< EOF\n{stdin}\nEOF"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def call_mwfn(inp_fn, stdin, cwd=None):
|
|
26
|
+
if cwd is None:
|
|
27
|
+
cwd = Path(".")
|
|
28
|
+
mwfn_cmd = get_cmd("mwfn")
|
|
29
|
+
cmd = [mwfn_cmd, inp_fn]
|
|
30
|
+
log(f"\n{mwfn_cmd} {inp_fn} {wrap_stdin(stdin)}")
|
|
31
|
+
proc = Popen(
|
|
32
|
+
cmd, universal_newlines=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=cwd
|
|
33
|
+
)
|
|
34
|
+
stdout, stderr = proc.communicate(stdin)
|
|
35
|
+
if "segmentation fault occurred" in stderr:
|
|
36
|
+
raise SegfaultException(
|
|
37
|
+
"Multiwfn segfaulted! Multiwfn seems to have problems "
|
|
38
|
+
"with systems >= 1000 basis functions. Maybe your system is too big."
|
|
39
|
+
)
|
|
40
|
+
proc.terminate()
|
|
41
|
+
return stdout, stderr
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def make_cdd(inp_fn, state, log_fn, cwd=None, keep=False, quality=2, prefix="S"):
|
|
45
|
+
"""Create CDD cube in cwd.
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
inp_fn : str
|
|
50
|
+
Filename of a .molden/.fchk file.
|
|
51
|
+
state : int
|
|
52
|
+
CDD cubes will be generated up to this state.
|
|
53
|
+
log_fn : str
|
|
54
|
+
Filename of the .log file.
|
|
55
|
+
cwd : str or Path, optional
|
|
56
|
+
If a different cwd should be used.
|
|
57
|
+
keep : bool
|
|
58
|
+
Wether to keep electron.cub and hole.cub, default is False.
|
|
59
|
+
quality : int
|
|
60
|
+
Quality of the cube. (1=low, 2=medium, 3=high).
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
assert quality in (1, 2, 3)
|
|
64
|
+
|
|
65
|
+
msg = (
|
|
66
|
+
f"Requested CDD calculation from Multiwfn for state {state} using "
|
|
67
|
+
f"{inp_fn} and {log_fn}"
|
|
68
|
+
)
|
|
69
|
+
log(msg)
|
|
70
|
+
|
|
71
|
+
stdin = f"""18
|
|
72
|
+
1
|
|
73
|
+
{log_fn}
|
|
74
|
+
{state}
|
|
75
|
+
1
|
|
76
|
+
{quality}
|
|
77
|
+
10
|
|
78
|
+
1
|
|
79
|
+
11
|
|
80
|
+
1
|
|
81
|
+
15
|
|
82
|
+
0
|
|
83
|
+
0
|
|
84
|
+
0
|
|
85
|
+
q
|
|
86
|
+
"""
|
|
87
|
+
stdout, stderr = call_mwfn(inp_fn, stdin, cwd=cwd)
|
|
88
|
+
|
|
89
|
+
if cwd is None:
|
|
90
|
+
cwd = "."
|
|
91
|
+
cwd = Path(cwd)
|
|
92
|
+
|
|
93
|
+
cube_fns = ("electron.cub", "hole.cub", "CDD.cub")
|
|
94
|
+
if not keep:
|
|
95
|
+
# always keep CDD.cub
|
|
96
|
+
for fn in cube_fns[:2]:
|
|
97
|
+
full_path = cwd / fn
|
|
98
|
+
os.remove(full_path)
|
|
99
|
+
# Rename cubes according to the current state
|
|
100
|
+
new_paths = list()
|
|
101
|
+
for fn in cube_fns:
|
|
102
|
+
old_path = cwd / fn
|
|
103
|
+
root, ext = os.path.splitext(fn)
|
|
104
|
+
new_path = cwd / f"{prefix}_{state:03d}_{root}{ext}"
|
|
105
|
+
try:
|
|
106
|
+
shutil.copy(old_path, new_path)
|
|
107
|
+
os.remove(old_path)
|
|
108
|
+
new_paths.append(new_path)
|
|
109
|
+
except FileNotFoundError:
|
|
110
|
+
pass
|
|
111
|
+
return new_paths
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def get_mwfn_exc_str(energies, Xa, Ya=None, Xb=None, Yb=None, thresh=1e-3):
|
|
115
|
+
"""Write plain text input for MWFN according to 3.21.
|
|
116
|
+
|
|
117
|
+
As of version 3.8 MWFN does not seem to handle this file when spin
|
|
118
|
+
labels are present, even though it is given as an example in the manual.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
# We only use the spin label for unrestricted calculations, where Xb is present.
|
|
122
|
+
spin_a = "A" if (Xb is not None) else ""
|
|
123
|
+
assert len(energies) == (
|
|
124
|
+
len(Xa) + 1
|
|
125
|
+
), "Found too few energies. Is the GS energy missing?"
|
|
126
|
+
exc_energies = (energies[1:] - energies[0]) * AU2EV
|
|
127
|
+
# states, occ, virt
|
|
128
|
+
nstates, occ_mos, _ = Xa.shape
|
|
129
|
+
|
|
130
|
+
exc_str = ""
|
|
131
|
+
mult = 1
|
|
132
|
+
log(f"Using dummy multiplicity={mult} in get_mwfn_exc_str")
|
|
133
|
+
|
|
134
|
+
def set_default(mat):
|
|
135
|
+
if mat is None:
|
|
136
|
+
mat = [None] * nstates
|
|
137
|
+
return mat
|
|
138
|
+
|
|
139
|
+
Ya = set_default(Ya)
|
|
140
|
+
Xb = set_default(Xb)
|
|
141
|
+
Yb = set_default(Yb)
|
|
142
|
+
|
|
143
|
+
def get_exc_lines(ci_coeffs, arrow, spin=""):
|
|
144
|
+
exc_lines = list()
|
|
145
|
+
for (occ, virt), coeff in np.ndenumerate(ci_coeffs):
|
|
146
|
+
if abs(coeff) < thresh:
|
|
147
|
+
continue
|
|
148
|
+
occ_mo = occ + 1
|
|
149
|
+
virt_mo = occ_mos + 1 + virt
|
|
150
|
+
exc_line = f"{occ_mo:>8d}{spin} {arrow} {virt_mo}{spin} {coeff: .5f}"
|
|
151
|
+
exc_lines.append(exc_line)
|
|
152
|
+
return exc_lines
|
|
153
|
+
|
|
154
|
+
for root_, (xa, ya, xb, yb, exc_en) in enumerate(
|
|
155
|
+
zip(Xa, Ya, Xb, Yb, exc_energies), 1
|
|
156
|
+
):
|
|
157
|
+
exc_str += f"Excited State {root_} {mult} {exc_en:.4f}\n"
|
|
158
|
+
# Excitations (X vector)
|
|
159
|
+
exc_lines = get_exc_lines(xa, "->", spin_a)
|
|
160
|
+
# De-Excitations (Y vector), if present
|
|
161
|
+
if ya is not None:
|
|
162
|
+
exc_lines += get_exc_lines(ya, "<-", spin_a)
|
|
163
|
+
if xb is not None:
|
|
164
|
+
exc_lines += get_exc_lines(xb, "->", "B")
|
|
165
|
+
if yb is not None:
|
|
166
|
+
exc_lines += get_exc_lines(yb, "<-", "B")
|
|
167
|
+
exc_str += "\n".join(exc_lines)
|
|
168
|
+
exc_str += "\n\n"
|
|
169
|
+
return exc_str
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import tempfile
|
|
3
|
+
|
|
4
|
+
from jinja2 import Template
|
|
5
|
+
|
|
6
|
+
from pysisyphus.config import get_cmd
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
TPL = """tolerance {{ tolerance }}
|
|
10
|
+
output {{ output_fn }}
|
|
11
|
+
filetype pdb
|
|
12
|
+
|
|
13
|
+
{% if solute_fn %}
|
|
14
|
+
# Solute
|
|
15
|
+
structure {{ solute_fn }}
|
|
16
|
+
number {{ solute_num }}
|
|
17
|
+
{% if solute_num == 1 %}
|
|
18
|
+
fixed 0. 0. 0. 0. 0. 0.
|
|
19
|
+
centerofmass
|
|
20
|
+
{% endif %}
|
|
21
|
+
end structure
|
|
22
|
+
{% endif %}
|
|
23
|
+
|
|
24
|
+
# Solvent
|
|
25
|
+
structure {{ solvent_fn }}
|
|
26
|
+
number {{ solvent_num }}
|
|
27
|
+
inside sphere 0. 0. 0. {{ sphere_radius }}
|
|
28
|
+
end structure
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def make_input(
|
|
33
|
+
output_fn,
|
|
34
|
+
solvent_fn,
|
|
35
|
+
solvent_num,
|
|
36
|
+
sphere_radius,
|
|
37
|
+
solute_fn=None,
|
|
38
|
+
solute_num=None,
|
|
39
|
+
tolerance=2.0,
|
|
40
|
+
):
|
|
41
|
+
tpl = Template(TPL)
|
|
42
|
+
rendered = tpl.render(
|
|
43
|
+
tolerance=tolerance,
|
|
44
|
+
output_fn=output_fn,
|
|
45
|
+
solute_fn=solute_fn,
|
|
46
|
+
solute_num=solute_num,
|
|
47
|
+
solvent_fn=solvent_fn,
|
|
48
|
+
solvent_num=solvent_num,
|
|
49
|
+
sphere_radius=sphere_radius,
|
|
50
|
+
)
|
|
51
|
+
return rendered
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def call_packmol(inp):
|
|
55
|
+
packmol_cmd = get_cmd("packmol")
|
|
56
|
+
|
|
57
|
+
with tempfile.NamedTemporaryFile(mode="w", dir=".") as tmp:
|
|
58
|
+
tmp.write(inp)
|
|
59
|
+
tmp.flush()
|
|
60
|
+
tmp.seek(0)
|
|
61
|
+
with open(tmp.name) as stdin_f:
|
|
62
|
+
proc = subprocess.run(
|
|
63
|
+
[packmol_cmd],
|
|
64
|
+
stdin=stdin_f,
|
|
65
|
+
stdout=subprocess.PIPE,
|
|
66
|
+
text=True,
|
|
67
|
+
)
|
|
68
|
+
# out = proc.stdout
|
|
69
|
+
# err = proc.stderr
|
|
70
|
+
|
|
71
|
+
return proc
|
pysisyphus/xyzloader.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pysisyphus.constants import BOHR2ANG
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def make_xyz_str(atoms, coords, comment=""):
|
|
9
|
+
assert len(atoms) == len(coords)
|
|
10
|
+
atoms = [a.capitalize() for a in atoms]
|
|
11
|
+
|
|
12
|
+
coord_fmt = "{: 03.8f}"
|
|
13
|
+
line_fmt = "{:>3s} " + " ".join(
|
|
14
|
+
[
|
|
15
|
+
coord_fmt,
|
|
16
|
+
]
|
|
17
|
+
* 3
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
body = [line_fmt.format(a, *xyz) for a, xyz in zip(atoms, coords)]
|
|
21
|
+
body = "\n".join(body)
|
|
22
|
+
|
|
23
|
+
return f"{len(atoms)}\n{comment}\n{body}"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def make_trj_str(atoms, coords_list, comments=None):
|
|
27
|
+
if comments is None:
|
|
28
|
+
comments = ["" for _ in coords_list]
|
|
29
|
+
xyz_strings = [
|
|
30
|
+
make_xyz_str(atoms, coords, comment)
|
|
31
|
+
for coords, comment in zip(coords_list, comments)
|
|
32
|
+
]
|
|
33
|
+
return "\n".join(xyz_strings)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def coords_to_trj(trj_fn, atoms, coords_list, comments=None):
|
|
37
|
+
coords = np.array(coords_list)
|
|
38
|
+
coords = coords.reshape(-1, len(atoms), 3) * BOHR2ANG
|
|
39
|
+
trj_str = make_trj_str(atoms, coords, comments)
|
|
40
|
+
with open(trj_fn, "w") as handle:
|
|
41
|
+
handle.write(trj_str)
|
|
42
|
+
return trj_fn
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def make_trj_str_from_geoms(geoms, comments=None, energy_comments=False):
|
|
46
|
+
atoms = geoms[0].atoms
|
|
47
|
+
coords_list = [geom.coords3d * BOHR2ANG for geom in geoms]
|
|
48
|
+
if energy_comments and comments is None:
|
|
49
|
+
comments = [str(geom._energy) for geom in geoms]
|
|
50
|
+
elif comments is not None:
|
|
51
|
+
assert len(comments) == len(geoms)
|
|
52
|
+
|
|
53
|
+
return make_trj_str(atoms, coords_list, comments)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def write_geoms_to_trj(geoms, fn, comments=None):
|
|
57
|
+
trj_str = make_trj_str_from_geoms(geoms, comments)
|
|
58
|
+
with open(fn, "w") as handle:
|
|
59
|
+
handle.write(trj_str)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def split_xyz_str(xyz_str):
|
|
63
|
+
"""Example:
|
|
64
|
+
|
|
65
|
+
xyz:
|
|
66
|
+
1
|
|
67
|
+
|
|
68
|
+
X -1.2 1.4 0.0
|
|
69
|
+
1
|
|
70
|
+
|
|
71
|
+
X 2.0 4.0 0.0
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
float_ = r"([\+\d\-\.]+)"
|
|
75
|
+
header_re = re.compile(r"(\d+)")
|
|
76
|
+
coord_re = re.compile(fr"[a-zA-Z]+\s+{float_}\s+{float_}\s+{float_}")
|
|
77
|
+
|
|
78
|
+
lines = [l.strip() for l in xyz_str.strip().split("\n")]
|
|
79
|
+
|
|
80
|
+
lines_remaining = len(lines)
|
|
81
|
+
cur_line = 0
|
|
82
|
+
valid_xyz_strs = list()
|
|
83
|
+
while lines_remaining:
|
|
84
|
+
header_mobj = header_re.match(lines[cur_line])
|
|
85
|
+
expect_lines = int(header_mobj[1])
|
|
86
|
+
slice_ = slice(
|
|
87
|
+
cur_line + 2, cur_line + 2 + expect_lines
|
|
88
|
+
) # lgtm [py/hash-unhashable-value]
|
|
89
|
+
check_lines = lines[slice_]
|
|
90
|
+
assert len(check_lines) == expect_lines
|
|
91
|
+
assert all([coord_re.match(line.strip()) for line in check_lines])
|
|
92
|
+
|
|
93
|
+
valid_xyz_strs.append(str(expect_lines) + "\n\n" + "\n".join(check_lines))
|
|
94
|
+
|
|
95
|
+
lines_read = expect_lines + 2
|
|
96
|
+
lines_remaining -= lines_read
|
|
97
|
+
cur_line += lines_read
|
|
98
|
+
atoms_coords = [parse_xyz_str(_, with_comment=False) for _ in valid_xyz_strs]
|
|
99
|
+
return atoms_coords
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def parse_xyz_str(xyz_str, with_comment):
|
|
103
|
+
"""Parse a xyz string.
|
|
104
|
+
|
|
105
|
+
Paramters
|
|
106
|
+
---------
|
|
107
|
+
xyz_str : str
|
|
108
|
+
The contents of a .xyz file.
|
|
109
|
+
with_comment : bool
|
|
110
|
+
Return comment line if True.
|
|
111
|
+
|
|
112
|
+
Returns
|
|
113
|
+
-------
|
|
114
|
+
atoms : list
|
|
115
|
+
List of length N (N = number of atoms) holding the
|
|
116
|
+
element symbols.
|
|
117
|
+
coords: np.array
|
|
118
|
+
An array of shape (N, 3) holding the xyz coordinates.
|
|
119
|
+
comment_line : str, optional
|
|
120
|
+
Comment line if with_comment argument was True.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
xyz_lines = xyz_str.strip().split("\n")
|
|
124
|
+
comment_line = xyz_lines[1]
|
|
125
|
+
|
|
126
|
+
# Only consider the first four items on a line
|
|
127
|
+
atom_num = int(xyz_lines[0])
|
|
128
|
+
atoms_present = len(xyz_lines) - 2
|
|
129
|
+
assert len(xyz_lines) == atom_num + 2, \
|
|
130
|
+
f"Expected {atom_num} atoms, but found only {atoms_present}!"
|
|
131
|
+
atoms_coords = [
|
|
132
|
+
line.strip().split()[:4] for line in xyz_str.strip().split("\n")[2:]
|
|
133
|
+
]
|
|
134
|
+
atoms, coords = zip(*[(a, c) for a, *c in atoms_coords])
|
|
135
|
+
coords = np.array(coords, dtype=float)
|
|
136
|
+
if with_comment:
|
|
137
|
+
return atoms, coords, comment_line
|
|
138
|
+
else:
|
|
139
|
+
return atoms, coords
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def parse_xyz_file(xyz_fn, with_comment=False):
|
|
143
|
+
with open(xyz_fn) as handle:
|
|
144
|
+
xyz_str = handle.read()
|
|
145
|
+
|
|
146
|
+
return parse_xyz_str(xyz_str, with_comment)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def parse_trj_file(trj_fn, with_comments=False):
|
|
150
|
+
with open(trj_fn) as handle:
|
|
151
|
+
trj_str = handle.read()
|
|
152
|
+
|
|
153
|
+
return parse_trj_str(trj_str, with_comments)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def parse_trj_str(trj_str, with_comments=False):
|
|
157
|
+
trj_lines = trj_str.strip().split("\n")
|
|
158
|
+
number_of_atoms = int(trj_lines[0].strip())
|
|
159
|
+
xyz_lines = number_of_atoms + 2
|
|
160
|
+
# Split the trj file in evenly sized strings
|
|
161
|
+
xyz_strs = [
|
|
162
|
+
"\n".join(trj_lines[i : i + xyz_lines])
|
|
163
|
+
for i in range(0, len(trj_lines), xyz_lines)
|
|
164
|
+
]
|
|
165
|
+
xyzs = [parse_xyz_str(xyz_str, with_comments) for xyz_str in xyz_strs]
|
|
166
|
+
|
|
167
|
+
assert len(xyzs) == (len(trj_lines) / xyz_lines)
|
|
168
|
+
return xyzs
|
pysisyphus/yaml_mods.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from pysisyphus.constants import AU2KJPERMOL, AU2KCALPERMOL, AU2EV, ANG2BOHR, BOHR2M
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import yaml
|
|
5
|
+
from yaml.constructor import ConstructorError
|
|
6
|
+
|
|
7
|
+
_UNIT_MAP = {
|
|
8
|
+
# Energies are converted to Hartree (E_h)
|
|
9
|
+
"Eh": 1,
|
|
10
|
+
"kJpermol": 1 / AU2KJPERMOL, # kJ mol⁻¹
|
|
11
|
+
"kcalpermol": 1 / AU2KCALPERMOL, # kcal mol⁻¹
|
|
12
|
+
"eV": 1 / AU2EV, # eV
|
|
13
|
+
# Times are converted to fs (1e-15 s)
|
|
14
|
+
"fs": 1,
|
|
15
|
+
"ps": 1e-3,
|
|
16
|
+
"ns": 1e-6,
|
|
17
|
+
# Lengths are converted to Bohr (a_0)
|
|
18
|
+
"a0": 1,
|
|
19
|
+
"angstrom": 1 / ANG2BOHR,
|
|
20
|
+
"nm": 1 / BOHR2M * 1e9,
|
|
21
|
+
"deg": np.pi / 180.0
|
|
22
|
+
}
|
|
23
|
+
_UNITS = list(_UNIT_MAP.keys())
|
|
24
|
+
UNITS = _UNITS
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_constructor(unit):
|
|
28
|
+
conv = _UNIT_MAP[unit]
|
|
29
|
+
|
|
30
|
+
def constructor(loader, node):
|
|
31
|
+
try:
|
|
32
|
+
data = float(loader.construct_scalar(node)) * conv
|
|
33
|
+
except ConstructorError:
|
|
34
|
+
data = np.array(loader.construct_sequence(node), dtype=float) * conv
|
|
35
|
+
return data
|
|
36
|
+
|
|
37
|
+
return constructor
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_loader(units=_UNITS):
|
|
41
|
+
loader = yaml.SafeLoader
|
|
42
|
+
for unit in units:
|
|
43
|
+
tag = f"!{unit}"
|
|
44
|
+
loader.add_constructor(tag, get_constructor(unit))
|
|
45
|
+
return loader
|