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,72 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pysisyphus.intcoords.Torsion import Torsion
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DummyTorsion(Torsion):
|
|
7
|
+
def __init__(self, indices, *args, fix_inner=True, **kwargs):
|
|
8
|
+
self.fix_inner = fix_inner
|
|
9
|
+
kwargs["calc_kwargs"] = ("fix_inner",)
|
|
10
|
+
super().__init__(indices, *args, **kwargs)
|
|
11
|
+
self.log("DummyTorsion is never checked for collinear atoms!")
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def get_fourth_coords(coords3d, indices, r=1.889, theta=90):
|
|
15
|
+
r"""
|
|
16
|
+
M N <- add
|
|
17
|
+
\ /
|
|
18
|
+
u v
|
|
19
|
+
\ /
|
|
20
|
+
P
|
|
21
|
+
m, o, p, n = indices
|
|
22
|
+
"""
|
|
23
|
+
_, O_, P_ = indices
|
|
24
|
+
# Center
|
|
25
|
+
P = coords3d[P_]
|
|
26
|
+
# Bond, pointing away from O to M
|
|
27
|
+
u = coords3d[O_] - P
|
|
28
|
+
# Direction of u along x axis (left/right)
|
|
29
|
+
sign = np.sign(u[0])
|
|
30
|
+
# Polar coordinates
|
|
31
|
+
x = r * np.cos(theta)
|
|
32
|
+
y = r * np.sin(theta)
|
|
33
|
+
# Translate from center with correct orientation
|
|
34
|
+
fourth_coords = P + (sign * x, sign * y, 0.0)
|
|
35
|
+
return fourth_coords
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def get_coords3d_and_indices_ext(coords3d, indices):
|
|
39
|
+
fourth_coords = DummyTorsion.get_fourth_coords(coords3d, indices)
|
|
40
|
+
fourth_ind = len(coords3d)
|
|
41
|
+
coords3d_ext = np.zeros((len(coords3d) + 1, 3))
|
|
42
|
+
coords3d_ext[:fourth_ind] = coords3d
|
|
43
|
+
coords3d_ext[fourth_ind] = fourth_coords
|
|
44
|
+
indices_ext = indices + [fourth_ind]
|
|
45
|
+
return coords3d_ext, indices_ext
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def _weight(*args, **kwargs):
|
|
49
|
+
return 1
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def _calculate(coords3d, indices, gradient=False, fix_inner=False):
|
|
53
|
+
coords3d_ext, indices_ext = DummyTorsion.get_coords3d_and_indices_ext(
|
|
54
|
+
coords3d, indices
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
results = Torsion._calculate(coords3d_ext, indices_ext, gradient=gradient)
|
|
58
|
+
if gradient:
|
|
59
|
+
val, grad = results
|
|
60
|
+
|
|
61
|
+
# Remove entries that belong to the dummy atom.
|
|
62
|
+
grad = grad[:-3]
|
|
63
|
+
|
|
64
|
+
# Zero out contributions of the inner two atoms in the torsion.
|
|
65
|
+
# So basically only the atom at the first index moves.
|
|
66
|
+
#
|
|
67
|
+
# This usually degrades optimization convergence.
|
|
68
|
+
if fix_inner:
|
|
69
|
+
grad.reshape(-1, 3)[indices_ext[1:3]] = 0.0
|
|
70
|
+
return val, grad.flatten()
|
|
71
|
+
else:
|
|
72
|
+
return results
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
from math import sin
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pysisyphus.intcoords.derivatives import dq_lb, d2q_lb
|
|
6
|
+
from pysisyphus.intcoords.Primitive import Primitive
|
|
7
|
+
from pysisyphus.linalg import cross3, norm3
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# [1] 10.1080/00268977200102361
|
|
11
|
+
# Hoy, 1972
|
|
12
|
+
# [2] 10.1063/1.474377
|
|
13
|
+
# Chuang, 1997
|
|
14
|
+
# [3] 10.1063/1.468630
|
|
15
|
+
# Jackels, 1995
|
|
16
|
+
# Refs. [2] and [3] give a short discussion of the linear bends.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class LinearBend(Primitive):
|
|
20
|
+
def __init__(self, *args, complement=False, **kwargs):
|
|
21
|
+
kwargs["calc_kwargs"] = ("complement", "cross_vec")
|
|
22
|
+
super().__init__(*args, **kwargs)
|
|
23
|
+
|
|
24
|
+
self.complement = complement
|
|
25
|
+
self.cross_vec = None
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def _weight(atoms, coords3d, indices, f_damping):
|
|
29
|
+
m, o, n = indices
|
|
30
|
+
rho_mo = LinearBend.rho(atoms, coords3d, (m, o))
|
|
31
|
+
rho_on = LinearBend.rho(atoms, coords3d, (o, n))
|
|
32
|
+
|
|
33
|
+
# Repeated code to avoid import of intcoords.Bend
|
|
34
|
+
u_dash = coords3d[m] - coords3d[o]
|
|
35
|
+
v_dash = coords3d[n] - coords3d[o]
|
|
36
|
+
u_norm = norm3(u_dash)
|
|
37
|
+
v_norm = norm3(v_dash)
|
|
38
|
+
u = u_dash / u_norm
|
|
39
|
+
v = v_dash / v_norm
|
|
40
|
+
rad = np.arccos(u.dot(v))
|
|
41
|
+
|
|
42
|
+
return (rho_mo * rho_on) ** 0.5 * (f_damping + (1 - f_damping) * sin(rad))
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def _get_orthogonal_direction(coords3d, indices, complement=False, cross_vec=None):
|
|
46
|
+
m, o, n = indices
|
|
47
|
+
u_dash = coords3d[m] - coords3d[o]
|
|
48
|
+
u_norm = norm3(u_dash)
|
|
49
|
+
u = u_dash / u_norm
|
|
50
|
+
|
|
51
|
+
if cross_vec is None:
|
|
52
|
+
cross_vec = LinearBend._get_cross_vec(coords3d, indices)
|
|
53
|
+
# Generate first orthogonal direction
|
|
54
|
+
w_dash = cross3(u, cross_vec)
|
|
55
|
+
w = w_dash / norm3(w_dash)
|
|
56
|
+
|
|
57
|
+
# Generate second orthogonal direction
|
|
58
|
+
if complement:
|
|
59
|
+
w = cross3(u, w)
|
|
60
|
+
return w
|
|
61
|
+
|
|
62
|
+
def calculate(self, coords3d, indices=None, gradient=False):
|
|
63
|
+
if self.cross_vec is None:
|
|
64
|
+
self.set_cross_vec(coords3d, indices)
|
|
65
|
+
|
|
66
|
+
return super().calculate(coords3d, indices, gradient)
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def _calculate(coords3d, indices, gradient=False, complement=False, cross_vec=None):
|
|
70
|
+
m, o, n = indices
|
|
71
|
+
u_dash = coords3d[m] - coords3d[o]
|
|
72
|
+
v_dash = coords3d[n] - coords3d[o]
|
|
73
|
+
u_norm = norm3(u_dash)
|
|
74
|
+
v_norm = norm3(v_dash)
|
|
75
|
+
w = LinearBend._get_orthogonal_direction(
|
|
76
|
+
coords3d, indices, complement, cross_vec
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
lb_rad = w.dot(cross3(u_dash, v_dash)) / (u_norm * v_norm)
|
|
80
|
+
|
|
81
|
+
if gradient:
|
|
82
|
+
# Fourth argument is the orthogonal direction
|
|
83
|
+
row = np.zeros_like(coords3d)
|
|
84
|
+
row[indices] = dq_lb(*coords3d[indices].flatten(), *w).reshape(-1, 3)
|
|
85
|
+
return lb_rad, row.flatten()
|
|
86
|
+
return lb_rad
|
|
87
|
+
|
|
88
|
+
def jacobian(self, coords3d, indices=None):
|
|
89
|
+
if self.cross_vec is None:
|
|
90
|
+
self.set_cross_vec(coords3d, indices)
|
|
91
|
+
|
|
92
|
+
return super().jacobian(coords3d, indices)
|
|
93
|
+
|
|
94
|
+
@staticmethod
|
|
95
|
+
def _jacobian(coords3d, indices, complement=False, cross_vec=None):
|
|
96
|
+
if cross_vec is None:
|
|
97
|
+
cross_vec = LinearBend._get_cross_vec(coords3d, indices)
|
|
98
|
+
|
|
99
|
+
w = LinearBend._get_orthogonal_direction(
|
|
100
|
+
coords3d, indices, complement, cross_vec
|
|
101
|
+
)
|
|
102
|
+
return d2q_lb(*coords3d[indices].flatten(), *w)
|
|
103
|
+
|
|
104
|
+
def __str__(self):
|
|
105
|
+
return f"LinearBend({tuple(self.indices)}, complement={self.complement})"
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pysisyphus.intcoords.Primitive import Primitive
|
|
4
|
+
from pysisyphus.intcoords.derivatives import dq_ld, d2q_ld
|
|
5
|
+
from pysisyphus.linalg import cross3, norm3
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LinearDisplacement(Primitive):
|
|
9
|
+
def __init__(self, *args, complement=False, **kwargs):
|
|
10
|
+
kwargs["calc_kwargs"] = ("complement", "cross_vec")
|
|
11
|
+
super().__init__(*args, **kwargs)
|
|
12
|
+
|
|
13
|
+
self.complement = complement
|
|
14
|
+
self.cross_vec = None
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def _weight(atoms, coords3d, indices, f_damping):
|
|
18
|
+
raise Exception("Not yet implemented!")
|
|
19
|
+
|
|
20
|
+
def calculate(self, coords3d, indices=None, gradient=False):
|
|
21
|
+
if self.cross_vec is None:
|
|
22
|
+
self.set_cross_vec(coords3d, indices)
|
|
23
|
+
|
|
24
|
+
return super().calculate(coords3d, indices, gradient)
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def _calculate(coords3d, indices, gradient=False, complement=False, cross_vec=None):
|
|
28
|
+
m, o, n = indices
|
|
29
|
+
w_dash = coords3d[n] - coords3d[m]
|
|
30
|
+
w = w_dash / norm3(w_dash)
|
|
31
|
+
|
|
32
|
+
u_dash = coords3d[m] - coords3d[o]
|
|
33
|
+
v_dash = coords3d[n] - coords3d[o]
|
|
34
|
+
u = u_dash / norm3(u_dash)
|
|
35
|
+
v = v_dash / norm3(v_dash)
|
|
36
|
+
|
|
37
|
+
# Vector for cross product to determine first orthogonal direction
|
|
38
|
+
if cross_vec is None:
|
|
39
|
+
cross_vec = LinearDisplacement._get_cross_vec(coords3d, indices)
|
|
40
|
+
|
|
41
|
+
if complement:
|
|
42
|
+
cross_vec = cross3(w, cross_vec)
|
|
43
|
+
cross_vec /= norm3(cross_vec)
|
|
44
|
+
|
|
45
|
+
# Orthogonal direction
|
|
46
|
+
y = cross3(w, cross_vec)
|
|
47
|
+
y /= norm3(y)
|
|
48
|
+
|
|
49
|
+
lin_disp = y.dot(u) + y.dot(v)
|
|
50
|
+
|
|
51
|
+
if gradient:
|
|
52
|
+
row = np.zeros_like(coords3d)
|
|
53
|
+
row[indices] = dq_ld(*coords3d[indices].flatten(), *cross_vec).reshape(-1, 3)
|
|
54
|
+
return lin_disp, row.flatten()
|
|
55
|
+
|
|
56
|
+
return lin_disp
|
|
57
|
+
|
|
58
|
+
def jacobian(self, coords3d, indices=None):
|
|
59
|
+
if self.cross_vec is None:
|
|
60
|
+
self.set_cross_vec(coords3d, indices)
|
|
61
|
+
|
|
62
|
+
return super().jacobian(coords3d, indices)
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _jacobian(coords3d, indices, complement=False, cross_vec=None):
|
|
66
|
+
if cross_vec is None:
|
|
67
|
+
cross_vec = LinearDisplacement._get_cross_vec(coords3d, indices)
|
|
68
|
+
|
|
69
|
+
if complement:
|
|
70
|
+
m, _, n = indices
|
|
71
|
+
w_dash = coords3d[n] - coords3d[m]
|
|
72
|
+
w = w_dash / norm3(w_dash)
|
|
73
|
+
cross_vec = cross3(w, cross_vec)
|
|
74
|
+
|
|
75
|
+
return d2q_ld(*coords3d[indices].flatten(), *cross_vec)
|
|
76
|
+
|
|
77
|
+
def __str__(self):
|
|
78
|
+
return (
|
|
79
|
+
f"LinearDisplacement({tuple(self.indices)}, complement={self.complement})"
|
|
80
|
+
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pysisyphus.intcoords.Primitive import Primitive
|
|
4
|
+
from pysisyphus.intcoords.derivatives import dq_oop, d2q_oop
|
|
5
|
+
from pysisyphus.linalg import cross3, norm3
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OutOfPlane(Primitive):
|
|
9
|
+
"""
|
|
10
|
+
[1] https://doi.org/10.1002/(SICI)1096-987X(19990730)20:10<1067::AID-JCC9>3.0.CO;2-V
|
|
11
|
+
Lee, 1999
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def _weight(atoms, coords3d, indices, f_damping):
|
|
16
|
+
raise Exception("Not yet implemented!")
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def _calculate(coords3d, indices, gradient=False):
|
|
20
|
+
"""
|
|
21
|
+
P
|
|
22
|
+
/ | \
|
|
23
|
+
/ | \
|
|
24
|
+
u' v' w'
|
|
25
|
+
/ | \
|
|
26
|
+
m n o
|
|
27
|
+
"""
|
|
28
|
+
# p is apex
|
|
29
|
+
m, n, o, p = indices
|
|
30
|
+
|
|
31
|
+
u_dash = coords3d[m] - coords3d[p]
|
|
32
|
+
v_dash = coords3d[n] - coords3d[p]
|
|
33
|
+
w_dash = coords3d[o] - coords3d[p]
|
|
34
|
+
|
|
35
|
+
u = u_dash / norm3(u_dash)
|
|
36
|
+
v = v_dash / norm3(v_dash)
|
|
37
|
+
w = w_dash / norm3(w_dash)
|
|
38
|
+
|
|
39
|
+
z_dash = cross3(u, v) + cross3(v, w) + cross3(w, u)
|
|
40
|
+
z = z_dash / norm3(z_dash)
|
|
41
|
+
|
|
42
|
+
oop_coord = z.dot(u)
|
|
43
|
+
|
|
44
|
+
if gradient:
|
|
45
|
+
grad = dq_oop(*coords3d[m], *coords3d[n], *coords3d[o], *coords3d[p])
|
|
46
|
+
grad = grad.reshape(4, 3)
|
|
47
|
+
row = np.zeros_like(coords3d)
|
|
48
|
+
row[m, :] = grad[0]
|
|
49
|
+
row[n, :] = grad[1]
|
|
50
|
+
row[o, :] = grad[2]
|
|
51
|
+
row[p, :] = grad[3]
|
|
52
|
+
row = row.flatten()
|
|
53
|
+
return oop_coord, row
|
|
54
|
+
|
|
55
|
+
return oop_coord
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def _jacobian(coords3d, indices):
|
|
59
|
+
return d2q_oop(*coords3d[indices].flatten())
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import itertools as it
|
|
2
|
+
from typing import Union, Sequence
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from pysisyphus.constants import BOHR2ANG
|
|
7
|
+
from pysisyphus.helpers_pure import OrderedEnum
|
|
8
|
+
from pysisyphus.intcoords import (
|
|
9
|
+
Bend,
|
|
10
|
+
Bend2,
|
|
11
|
+
BondedFragment,
|
|
12
|
+
DummyImproper,
|
|
13
|
+
DummyTorsion,
|
|
14
|
+
DistanceFunction,
|
|
15
|
+
CartesianX,
|
|
16
|
+
CartesianY,
|
|
17
|
+
CartesianZ,
|
|
18
|
+
LinearBend,
|
|
19
|
+
LinearDisplacement,
|
|
20
|
+
OutOfPlane,
|
|
21
|
+
RobustTorsion1,
|
|
22
|
+
RobustTorsion2,
|
|
23
|
+
RotationA,
|
|
24
|
+
RotationB,
|
|
25
|
+
RotationC,
|
|
26
|
+
Stretch,
|
|
27
|
+
TranslationX,
|
|
28
|
+
TranslationY,
|
|
29
|
+
TranslationZ,
|
|
30
|
+
Torsion,
|
|
31
|
+
Torsion2,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class PrimTypes(OrderedEnum):
|
|
36
|
+
BOND = 0
|
|
37
|
+
AUX_BOND = 1
|
|
38
|
+
HYDROGEN_BOND = 2
|
|
39
|
+
INTERFRAG_BOND = 3
|
|
40
|
+
AUX_INTERFRAG_BOND = 4
|
|
41
|
+
BEND = 5
|
|
42
|
+
LINEAR_BEND = 6
|
|
43
|
+
LINEAR_BEND_COMPLEMENT = 7
|
|
44
|
+
PROPER_DIHEDRAL = 8
|
|
45
|
+
IMPROPER_DIHEDRAL = 9
|
|
46
|
+
OUT_OF_PLANE = 10
|
|
47
|
+
LINEAR_DISPLACEMENT = 11
|
|
48
|
+
LINEAR_DISPLACEMENT_COMPLEMENT = 12
|
|
49
|
+
TRANSLATION = 13
|
|
50
|
+
TRANSLATION_X = 14
|
|
51
|
+
TRANSLATION_Y = 15
|
|
52
|
+
TRANSLATION_Z = 16
|
|
53
|
+
ROTATION = 17
|
|
54
|
+
ROTATION_A = 18
|
|
55
|
+
ROTATION_B = 19
|
|
56
|
+
ROTATION_C = 20
|
|
57
|
+
CARTESIAN = 21
|
|
58
|
+
CARTESIAN_X = 22
|
|
59
|
+
CARTESIAN_Y = 23
|
|
60
|
+
CARTESIAN_Z = 24
|
|
61
|
+
BONDED_FRAGMENT = 25
|
|
62
|
+
DUMMY_TORSION = 26
|
|
63
|
+
DISTANCE_FUNCTION = 27
|
|
64
|
+
# atan2 based bend and torsion
|
|
65
|
+
BEND2 = 28
|
|
66
|
+
PROPER_DIHEDRAL2 = 29
|
|
67
|
+
DUMMY_IMPROPER = 30
|
|
68
|
+
ROBUST_TORSION1 = 31
|
|
69
|
+
ROBUST_TORSION2 = 32
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
PrimTypeLike = Union[PrimTypes, str]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# Alias for easier access
|
|
76
|
+
PT = PrimTypes
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
PrimTypeShortcuts = {
|
|
80
|
+
"X": [PT.CARTESIAN_X],
|
|
81
|
+
"Y": [PT.CARTESIAN_Y],
|
|
82
|
+
"Z": [PT.CARTESIAN_Z],
|
|
83
|
+
"XY": [PT.CARTESIAN_X, PT.CARTESIAN_Y],
|
|
84
|
+
"XZ": [PT.CARTESIAN_X, PT.CARTESIAN_Z],
|
|
85
|
+
"YZ": [PT.CARTESIAN_Y, PT.CARTESIAN_Z],
|
|
86
|
+
"XYZ": [PT.CARTESIAN_X, PT.CARTESIAN_Y, PT.CARTESIAN_Z],
|
|
87
|
+
"ATOM": [PT.CARTESIAN_X, PT.CARTESIAN_Y, PT.CARTESIAN_Z],
|
|
88
|
+
# Primitive aliases
|
|
89
|
+
"B": [PT.BOND],
|
|
90
|
+
"A": [PT.BEND],
|
|
91
|
+
"A2": [PT.BEND2],
|
|
92
|
+
"D": [PT.PROPER_DIHEDRAL],
|
|
93
|
+
"D2": [PT.PROPER_DIHEDRAL2],
|
|
94
|
+
"DIHEDRAL": [PT.PROPER_DIHEDRAL],
|
|
95
|
+
"DIHEDRAL2": [PT.PROPER_DIHEDRAL2],
|
|
96
|
+
"TORSION": [PT.PROPER_DIHEDRAL],
|
|
97
|
+
"TORSION2": [PT.PROPER_DIHEDRAL2],
|
|
98
|
+
"RTORSION1": [PT.ROBUST_TORSION1],
|
|
99
|
+
"RTORSION2": [PT.ROBUST_TORSION2],
|
|
100
|
+
# Translation & Rotation coordinates
|
|
101
|
+
"TRANSLATION": [PT.TRANSLATION_X, PT.TRANSLATION_Y, PT.TRANSLATION_Z],
|
|
102
|
+
"ROTATION": [PT.ROTATION_A, PT.ROTATION_B, PT.ROTATION_C],
|
|
103
|
+
"DIST_FUNC": [PT.DISTANCE_FUNCTION],
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# The tuples below can be used to decide whether a given type belongs
|
|
107
|
+
# to a certain class of primitive.
|
|
108
|
+
Bonds = (
|
|
109
|
+
PT.BOND,
|
|
110
|
+
PT.AUX_BOND,
|
|
111
|
+
PT.HYDROGEN_BOND,
|
|
112
|
+
PT.INTERFRAG_BOND,
|
|
113
|
+
PT.AUX_INTERFRAG_BOND,
|
|
114
|
+
PT.DISTANCE_FUNCTION,
|
|
115
|
+
)
|
|
116
|
+
Bends = (PT.BEND, PT.BEND2)
|
|
117
|
+
LinearBends = (
|
|
118
|
+
PT.LINEAR_BEND,
|
|
119
|
+
PT.LINEAR_BEND_COMPLEMENT,
|
|
120
|
+
PT.LINEAR_DISPLACEMENT,
|
|
121
|
+
PT.LINEAR_DISPLACEMENT_COMPLEMENT,
|
|
122
|
+
)
|
|
123
|
+
Dihedrals = (
|
|
124
|
+
PT.PROPER_DIHEDRAL,
|
|
125
|
+
PT.IMPROPER_DIHEDRAL,
|
|
126
|
+
PT.PROPER_DIHEDRAL2,
|
|
127
|
+
PT.DUMMY_IMPROPER,
|
|
128
|
+
PT.ROBUST_TORSION1,
|
|
129
|
+
PT.ROBUST_TORSION2,
|
|
130
|
+
)
|
|
131
|
+
OutOfPlanes = (PT.OUT_OF_PLANE,)
|
|
132
|
+
Cartesians = (PT.CARTESIAN_X, PT.CARTESIAN_Y, PT.CARTESIAN_Z)
|
|
133
|
+
Rotations = (PT.ROTATION_A, PT.ROTATION_B, PT.ROTATION_C)
|
|
134
|
+
Translations = (
|
|
135
|
+
PT.TRANSLATION_X,
|
|
136
|
+
PT.TRANSLATION_Y,
|
|
137
|
+
PT.TRANSLATION_Z,
|
|
138
|
+
PT.BONDED_FRAGMENT,
|
|
139
|
+
)
|
|
140
|
+
DummyCoords = (PT.DUMMY_TORSION,)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def get_rot_coord(cls):
|
|
144
|
+
def func(indices, ref_coords3d):
|
|
145
|
+
return cls(indices, ref_coords3d=ref_coords3d)
|
|
146
|
+
|
|
147
|
+
return func
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_bonded_frag_coord():
|
|
151
|
+
def func(indices):
|
|
152
|
+
indices_ = indices[:-2]
|
|
153
|
+
bond_indices = indices[-2:]
|
|
154
|
+
return BondedFragment(indices_, bond_indices=bond_indices)
|
|
155
|
+
|
|
156
|
+
return func
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def get_dist_func():
|
|
160
|
+
def func(indices):
|
|
161
|
+
indices_ = indices[:4]
|
|
162
|
+
coeff = indices[4]
|
|
163
|
+
return DistanceFunction(indices_, coeff=coeff)
|
|
164
|
+
|
|
165
|
+
return func
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# Maps primitive types to their classes
|
|
169
|
+
PrimMap = {
|
|
170
|
+
PT.BOND: Stretch,
|
|
171
|
+
PT.AUX_BOND: Stretch,
|
|
172
|
+
PT.HYDROGEN_BOND: Stretch,
|
|
173
|
+
PT.INTERFRAG_BOND: Stretch,
|
|
174
|
+
PT.AUX_INTERFRAG_BOND: Stretch,
|
|
175
|
+
PT.BEND: Bend,
|
|
176
|
+
PT.BEND2: Bend2,
|
|
177
|
+
PT.LINEAR_BEND: LinearBend,
|
|
178
|
+
PT.LINEAR_BEND_COMPLEMENT: lambda indices: LinearBend(indices, complement=True),
|
|
179
|
+
PT.PROPER_DIHEDRAL: lambda indices: Torsion(indices, periodic=True),
|
|
180
|
+
PT.PROPER_DIHEDRAL2: lambda indices: Torsion2(indices, periodic=True),
|
|
181
|
+
PT.IMPROPER_DIHEDRAL: lambda indices: Torsion(indices, periodic=True),
|
|
182
|
+
PT.ROBUST_TORSION1: lambda indices: RobustTorsion1(indices),
|
|
183
|
+
PT.ROBUST_TORSION2: lambda indices: RobustTorsion2(indices),
|
|
184
|
+
PT.OUT_OF_PLANE: OutOfPlane,
|
|
185
|
+
PT.LINEAR_DISPLACEMENT: LinearDisplacement,
|
|
186
|
+
PT.LINEAR_DISPLACEMENT_COMPLEMENT: lambda indices: LinearDisplacement(
|
|
187
|
+
indices, complement=True
|
|
188
|
+
),
|
|
189
|
+
PT.TRANSLATION_X: TranslationX,
|
|
190
|
+
PT.TRANSLATION_Y: TranslationY,
|
|
191
|
+
PT.TRANSLATION_Z: TranslationZ,
|
|
192
|
+
PT.ROTATION_A: get_rot_coord(RotationA),
|
|
193
|
+
PT.ROTATION_B: get_rot_coord(RotationB),
|
|
194
|
+
PT.ROTATION_C: get_rot_coord(RotationC),
|
|
195
|
+
PT.CARTESIAN_X: CartesianX,
|
|
196
|
+
PT.CARTESIAN_Y: CartesianY,
|
|
197
|
+
PT.CARTESIAN_Z: CartesianZ,
|
|
198
|
+
PT.BONDED_FRAGMENT: get_bonded_frag_coord(),
|
|
199
|
+
PT.DUMMY_TORSION: lambda indices: DummyTorsion(
|
|
200
|
+
indices,
|
|
201
|
+
periodic=True,
|
|
202
|
+
),
|
|
203
|
+
PT.DISTANCE_FUNCTION: get_dist_func(),
|
|
204
|
+
PT.DUMMY_IMPROPER: lambda indices: DummyImproper(
|
|
205
|
+
indices,
|
|
206
|
+
periodic=True,
|
|
207
|
+
),
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def normalize_prim_input(prim_inp):
|
|
212
|
+
"""Normalize input for define_prims and constrain_prims
|
|
213
|
+
|
|
214
|
+
The intcoords.RedundantCoords constructor expects lists of integer lists
|
|
215
|
+
(tuples) for arguments like 'define_prims' and 'constrain_prims'. The first item
|
|
216
|
+
of every list determines the type of primitive coordinate. Currently
|
|
217
|
+
there are about 20 different types and it is hard to remember all of
|
|
218
|
+
them.
|
|
219
|
+
|
|
220
|
+
So we also allow a more human friendly input, that is normalized here.
|
|
221
|
+
The most common primitives are:
|
|
222
|
+
|
|
223
|
+
0: BOND
|
|
224
|
+
5: BEND
|
|
225
|
+
8: PROPER_DIHEDRAL
|
|
226
|
+
|
|
227
|
+
This function maps inputs like ["BOND", 1, 2] to [PrimTypes.BOND, 1, 2] etc.
|
|
228
|
+
|
|
229
|
+
Always returns a list of tuples, as some prim_inps expand to multiple
|
|
230
|
+
coordinates, e.g., XYZ or ATOM.
|
|
231
|
+
"""
|
|
232
|
+
if prim_inp is None:
|
|
233
|
+
return []
|
|
234
|
+
|
|
235
|
+
prim_type, *indices = prim_inp
|
|
236
|
+
indices = list(map(int, indices))
|
|
237
|
+
|
|
238
|
+
# Nothing to do
|
|
239
|
+
if isinstance(prim_type, PrimTypes):
|
|
240
|
+
return [prim_inp]
|
|
241
|
+
|
|
242
|
+
# First check if we got something like an integer
|
|
243
|
+
try:
|
|
244
|
+
return [tuple([PrimTypes(int(prim_type))] + indices)]
|
|
245
|
+
# Raised when prim_type is, e.g., "BOND"
|
|
246
|
+
except ValueError:
|
|
247
|
+
pass
|
|
248
|
+
|
|
249
|
+
# Check if we got a PrimType name
|
|
250
|
+
try:
|
|
251
|
+
prim_type_ = getattr(PrimTypes, str(prim_type).upper())
|
|
252
|
+
return [tuple([prim_type_] + indices)]
|
|
253
|
+
except AttributeError:
|
|
254
|
+
pass
|
|
255
|
+
|
|
256
|
+
# Check if we got a shortcut, e.g, X/Y/Z/XYZ/ATOM etc.
|
|
257
|
+
try:
|
|
258
|
+
prim_types_ = PrimTypeShortcuts[str(prim_type).upper()]
|
|
259
|
+
return [tuple([prim_type_] + indices) for prim_type_ in prim_types_]
|
|
260
|
+
except KeyError as error:
|
|
261
|
+
print(f"Could not normalize 'prim_inp'={prim_inp}!")
|
|
262
|
+
raise error
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def normalize_prim_inputs(prim_inps):
|
|
266
|
+
# Flatten list of tuples
|
|
267
|
+
return list(it.chain(*[normalize_prim_input(pi) for pi in prim_inps]))
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def prims_from_prim_inputs(prim_inps):
|
|
271
|
+
norm_prim_inps = normalize_prim_inputs(prim_inps)
|
|
272
|
+
prims = [PrimMap[prim_type](indices) for prim_type, *indices in norm_prim_inps]
|
|
273
|
+
return prims
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def prim_for_human(prim_type: PrimTypes, val: Sequence[int]):
|
|
277
|
+
if prim_type in Bonds:
|
|
278
|
+
val_conv = val * BOHR2ANG
|
|
279
|
+
unit = " Å"
|
|
280
|
+
elif prim_type in Bends:
|
|
281
|
+
unit = "°"
|
|
282
|
+
val_conv = np.rad2deg(val)
|
|
283
|
+
else:
|
|
284
|
+
val_conv = val
|
|
285
|
+
unit = ""
|
|
286
|
+
return val_conv, unit
|