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,80 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import random
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PrimInternal:
|
|
8
|
+
def __init__(self, inds, val, grad=None):
|
|
9
|
+
self.inds = inds
|
|
10
|
+
self.val = val
|
|
11
|
+
self.grad = grad
|
|
12
|
+
|
|
13
|
+
def __str__(self):
|
|
14
|
+
return f"PrimInternal({self.inds})"
|
|
15
|
+
|
|
16
|
+
def __repr__(self):
|
|
17
|
+
return f"PrimInternal({self.inds}, {self.val:.4f})"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def eval_primitives(coords3d, primitives):
|
|
21
|
+
prim_internals = list()
|
|
22
|
+
for primitive in primitives:
|
|
23
|
+
value, gradient = primitive.calculate(coords3d, gradient=True)
|
|
24
|
+
prim_internal = PrimInternal(primitive.indices, value, gradient)
|
|
25
|
+
prim_internals.append(prim_internal)
|
|
26
|
+
return prim_internals
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def eval_B(coords3d, primitives):
|
|
30
|
+
prim_internals = eval_primitives(coords3d, primitives)
|
|
31
|
+
return np.array([prim_int.grad for prim_int in prim_internals])
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def check_primitives(coords3d, primitives, B=None, thresh=1e-6, logger=None):
|
|
35
|
+
assert len(primitives) > 0
|
|
36
|
+
|
|
37
|
+
def log(msg, level=logging.DEBUG):
|
|
38
|
+
if logger is not None:
|
|
39
|
+
logger.log(level, msg)
|
|
40
|
+
|
|
41
|
+
if B is None:
|
|
42
|
+
B = eval_B(coords3d, primitives)
|
|
43
|
+
G = B.T.dot(B)
|
|
44
|
+
w, v = np.linalg.eigh(G)
|
|
45
|
+
nonzero_inds = np.abs(w) > thresh
|
|
46
|
+
# More coordinates may be expected when collinear atoms are present.
|
|
47
|
+
expected = coords3d.size - 6
|
|
48
|
+
nonzero_num = sum(nonzero_inds)
|
|
49
|
+
missing = expected - nonzero_num
|
|
50
|
+
if missing > 0:
|
|
51
|
+
log(
|
|
52
|
+
"Not enough internal coordinates defined! Expected at least "
|
|
53
|
+
f"{expected} nonzero eigenvalues. Found only {nonzero_num}!"
|
|
54
|
+
)
|
|
55
|
+
nonzero_w = w[nonzero_inds]
|
|
56
|
+
# Condition number
|
|
57
|
+
kappa = abs(nonzero_w.max() / nonzero_w.min())
|
|
58
|
+
log(f"Condition number of B^T.B=G: {kappa:.4e}")
|
|
59
|
+
return missing + 1, kappa
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def augment_primitives(missing_prims, coords3d, prim_indices, fragments):
|
|
63
|
+
add_bonds = list()
|
|
64
|
+
add_bends = list()
|
|
65
|
+
add_dihedrals = list()
|
|
66
|
+
|
|
67
|
+
fragment_tpls = [tuple(fragment) for fragment in fragments]
|
|
68
|
+
if len(fragments) > 1:
|
|
69
|
+
bond_inds = prim_indices[0]
|
|
70
|
+
bond_sets = [frozenset(bond) for bond in bond_inds]
|
|
71
|
+
while missing_prims > 0:
|
|
72
|
+
random.shuffle(fragment_tpls)
|
|
73
|
+
frag1, frag2 = fragment_tpls[:2]
|
|
74
|
+
atom1 = random.choice(frag1)
|
|
75
|
+
atom2 = random.choice(frag2)
|
|
76
|
+
bond_set = frozenset((atom1, atom2))
|
|
77
|
+
if (bond_set not in bond_sets) and (bond_set not in add_bonds):
|
|
78
|
+
add_bonds.append(list(bond_set))
|
|
79
|
+
missing_prims -= 1
|
|
80
|
+
return add_bonds, add_bends, add_dihedrals
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class NeedNewInternalsException(Exception):
|
|
2
|
+
|
|
3
|
+
def __init__(
|
|
4
|
+
self, coords3d, *args, invalid_inds=None, invalid_prims=None, **kwargs
|
|
5
|
+
):
|
|
6
|
+
super().__init__(*args, **kwargs)
|
|
7
|
+
|
|
8
|
+
self.coords3d = coords3d
|
|
9
|
+
if invalid_inds is None:
|
|
10
|
+
invalid_inds = ()
|
|
11
|
+
self.invalid_inds = invalid_inds
|
|
12
|
+
if invalid_prims is None:
|
|
13
|
+
invalid_prims = ()
|
|
14
|
+
self.invalid_prims = invalid_prims
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RebuiltInternalsException(Exception):
|
|
18
|
+
|
|
19
|
+
def __init__(self, *args, typed_prims=None, **kwargs):
|
|
20
|
+
super().__init__(*args, **kwargs)
|
|
21
|
+
|
|
22
|
+
self.typed_prims = typed_prims
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DifferentPrimitivesException(Exception):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DifferentCoordLengthsException(Exception):
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class PrimitiveNotDefinedException(Exception):
|
|
34
|
+
|
|
35
|
+
def __init__(self, typed_prim, *args, **kwargs):
|
|
36
|
+
self.typed_prim = typed_prim
|
|
37
|
+
super().__init__(*args, **kwargs)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import itertools as it
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def fin_diff_prim(primitive, coords3d, delta=1e-6):
|
|
7
|
+
"""Derivatives of a primitive internal gradient wrt its defining
|
|
8
|
+
cartesian coordinates."""
|
|
9
|
+
displacement_inds = [(i, j) for i, j in it.product(primitive.indices, (0, 1, 2))]
|
|
10
|
+
|
|
11
|
+
prim_grads = list()
|
|
12
|
+
for atom_ind, ax_ind in displacement_inds:
|
|
13
|
+
plus = coords3d.copy()
|
|
14
|
+
plus[atom_ind, ax_ind] += delta
|
|
15
|
+
plus_val = primitive.calculate(plus)
|
|
16
|
+
minus = coords3d.copy()
|
|
17
|
+
minus[atom_ind, ax_ind] -= delta
|
|
18
|
+
minus_val = primitive.calculate(minus)
|
|
19
|
+
# Select the appropriate item of the primitive internal gradient
|
|
20
|
+
prim_grad = (plus_val - minus_val) / (2 * delta)
|
|
21
|
+
prim_grads.append(prim_grad)
|
|
22
|
+
prim_grads = np.array(prim_grads)
|
|
23
|
+
return prim_grads
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def fin_diff_B(primitive, coords3d, delta=1e-6):
|
|
27
|
+
"""Derivatives of a primitive internal gradient wrt its defining
|
|
28
|
+
cartesian coordinates."""
|
|
29
|
+
displacement_inds = [(i, j) for i, j in it.product(primitive.indices, (0, 1, 2))]
|
|
30
|
+
|
|
31
|
+
B_grads = list()
|
|
32
|
+
for grad_atom_ind, grad_ax_ind in displacement_inds:
|
|
33
|
+
# Calculate the derivative of an entry of the Wilson B-matrix.
|
|
34
|
+
for atom_ind, ax_ind in displacement_inds:
|
|
35
|
+
plus = coords3d.copy()
|
|
36
|
+
plus[atom_ind, ax_ind] += delta
|
|
37
|
+
_, plus_val = primitive.calculate(plus, gradient=True)
|
|
38
|
+
plus_val = plus_val.reshape(-1, 3)
|
|
39
|
+
minus = coords3d.copy()
|
|
40
|
+
minus[atom_ind, ax_ind] -= delta
|
|
41
|
+
_, minus_val = primitive.calculate(minus, gradient=True)
|
|
42
|
+
minus_val = minus_val.reshape(-1, 3)
|
|
43
|
+
# Select the appropriate item of the primitive internal gradient
|
|
44
|
+
B_grad = (plus_val[grad_atom_ind, grad_ax_ind]
|
|
45
|
+
- minus_val[grad_atom_ind, grad_ax_ind]) / (2 * delta)
|
|
46
|
+
B_grads.append(B_grad)
|
|
47
|
+
B_grads = np.array(B_grads)
|
|
48
|
+
return B_grads
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Johannes Steinmetzer 2020
|
|
4
|
+
# As describend in:
|
|
5
|
+
# V. Bakken, T. Helgaker, J. Chem. Phys., 117, 20, 2002
|
|
6
|
+
# [1] https://aip.scitation.org/doi/abs/10.1063/1.1515483
|
|
7
|
+
# [2] https://doi.org/10.1002/(SICI)1096-987X(19960115)17:1<49::AID-JCC5>3.0.CO;2-0
|
|
8
|
+
# [3] TRANSITION-STATE OPTIMIZATION METHODS USING INTERNAL COORDINATES
|
|
9
|
+
# Sandra Rabi, PhD Thesis
|
|
10
|
+
|
|
11
|
+
from collections import namedtuple
|
|
12
|
+
import itertools as it
|
|
13
|
+
import random
|
|
14
|
+
import string
|
|
15
|
+
import textwrap
|
|
16
|
+
|
|
17
|
+
from jinja2 import Template
|
|
18
|
+
import sympy as sym
|
|
19
|
+
from sympy import cse
|
|
20
|
+
from sympy.codegen.ast import Assignment
|
|
21
|
+
from sympy.printing.pycode import pycode, MpmathPrinter
|
|
22
|
+
from sympy.vector import CoordSys3D
|
|
23
|
+
from sympy.tensor.array.dense_ndim_array import ImmutableDenseNDimArray
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
FuncResult = namedtuple("FuncResult", "d0 d1 d2 f0 f1 f2")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def make_py_func(exprs, args=None, name=None, comment="", use_mpmath=False):
|
|
30
|
+
if args is None:
|
|
31
|
+
args = list()
|
|
32
|
+
if name is None:
|
|
33
|
+
name = "func_" + "".join(
|
|
34
|
+
[random.choice(string.ascii_letters) for i in range(8)]
|
|
35
|
+
)
|
|
36
|
+
arg_strs = [arg.strip() for arg in args.split(",")]
|
|
37
|
+
|
|
38
|
+
is_scalar = not isinstance(exprs, ImmutableDenseNDimArray)
|
|
39
|
+
if is_scalar:
|
|
40
|
+
repls, reduced = cse(exprs)
|
|
41
|
+
reduced = reduced[0]
|
|
42
|
+
else:
|
|
43
|
+
if len(exprs.shape) == 2:
|
|
44
|
+
exprs = it.chain(*exprs)
|
|
45
|
+
repls, reduced = cse(list(exprs))
|
|
46
|
+
|
|
47
|
+
print_func = pycode
|
|
48
|
+
if use_mpmath:
|
|
49
|
+
print_func = MpmathPrinter().doprint
|
|
50
|
+
|
|
51
|
+
assignments = [Assignment(lhs, rhs) for lhs, rhs in repls]
|
|
52
|
+
py_lines = [print_func(as_) for as_ in assignments]
|
|
53
|
+
return_val = print_func(reduced)
|
|
54
|
+
|
|
55
|
+
tpl = Template(
|
|
56
|
+
"""
|
|
57
|
+
def {{ name }}({{ args }}):
|
|
58
|
+
{% if comment %}
|
|
59
|
+
\"\"\"{{ comment }}\"\"\"
|
|
60
|
+
{% endif %}
|
|
61
|
+
|
|
62
|
+
{% if use_mpmath %}
|
|
63
|
+
{% for arg in arg_strs %}
|
|
64
|
+
{{ arg }} = mpmath.mpf({{ arg }})
|
|
65
|
+
{% endfor %}
|
|
66
|
+
{% endif %}
|
|
67
|
+
|
|
68
|
+
{% for line in py_lines %}
|
|
69
|
+
{{ line }}
|
|
70
|
+
{% endfor %}
|
|
71
|
+
|
|
72
|
+
{% if is_scalar %}
|
|
73
|
+
return {{ return_val }}
|
|
74
|
+
{% else %}
|
|
75
|
+
return np.array({{ return_val }}, dtype=np.float64)
|
|
76
|
+
{% endif %}
|
|
77
|
+
""",
|
|
78
|
+
trim_blocks=True,
|
|
79
|
+
lstrip_blocks=True,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
rendered = textwrap.dedent(
|
|
83
|
+
tpl.render(
|
|
84
|
+
name=name,
|
|
85
|
+
args=args,
|
|
86
|
+
py_lines=py_lines,
|
|
87
|
+
return_val=return_val,
|
|
88
|
+
comment=comment,
|
|
89
|
+
is_scalar=is_scalar,
|
|
90
|
+
use_mpmath=use_mpmath,
|
|
91
|
+
arg_strs=arg_strs,
|
|
92
|
+
)
|
|
93
|
+
).strip()
|
|
94
|
+
return rendered
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# def make_deriv_funcs(base_expr, dx, args, names, comments):
|
|
98
|
+
def make_deriv_funcs(base_expr, dx, args, names, comment, use_mpmath=True):
|
|
99
|
+
q_name, d1_name, d2_name = names
|
|
100
|
+
q_comment, d1_comment, d2_comment = [
|
|
101
|
+
comment + add
|
|
102
|
+
for add in [
|
|
103
|
+
"",
|
|
104
|
+
", first derivative wrt. Cartesians",
|
|
105
|
+
", 2nd derivative wrt. Cartesians",
|
|
106
|
+
]
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
# Actual function
|
|
110
|
+
print(f"\tmpmath: {use_mpmath}")
|
|
111
|
+
print("\tFunction")
|
|
112
|
+
q_func = make_py_func(
|
|
113
|
+
base_expr, args=args, name=q_name, comment=q_comment, use_mpmath=use_mpmath
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# First derivative
|
|
117
|
+
print("\t1st derivative")
|
|
118
|
+
deriv1 = sym.derive_by_array(base_expr, dx)
|
|
119
|
+
deriv1_func = make_py_func(
|
|
120
|
+
deriv1, args=args, name=d1_name, comment=d1_comment, use_mpmath=use_mpmath
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Second derivative
|
|
124
|
+
print("\t2nd derivative")
|
|
125
|
+
deriv2 = sym.derive_by_array(deriv1, dx)
|
|
126
|
+
deriv2_func = make_py_func(
|
|
127
|
+
deriv2, args=args, name=d2_name, comment=d2_comment, use_mpmath=use_mpmath
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
return FuncResult(
|
|
131
|
+
# Expressions
|
|
132
|
+
d0=base_expr,
|
|
133
|
+
d1=deriv1,
|
|
134
|
+
d2=deriv2,
|
|
135
|
+
# Functions
|
|
136
|
+
f0=q_func,
|
|
137
|
+
f1=deriv1_func,
|
|
138
|
+
f2=deriv2_func,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def generate_wilson(generate=None, out_fn="derivatives.py", use_mpmath=False):
|
|
143
|
+
m0, m1, m2, n0, n1, n2, o0, o1, o2, p0, p1, p2 = sym.symbols("m:3 n:3 o:3 p:3")
|
|
144
|
+
|
|
145
|
+
# Coordinate system
|
|
146
|
+
Sys = CoordSys3D("Sys")
|
|
147
|
+
M = Sys.origin.locate_new("M", m0 * Sys.i + m1 * Sys.j + m2 * Sys.k)
|
|
148
|
+
N = Sys.origin.locate_new("N", n0 * Sys.i + n1 * Sys.j + n2 * Sys.k)
|
|
149
|
+
O = Sys.origin.locate_new("O", o0 * Sys.i + o1 * Sys.j + o2 * Sys.k)
|
|
150
|
+
P = Sys.origin.locate_new("P", p0 * Sys.i + p1 * Sys.j + p2 * Sys.k)
|
|
151
|
+
|
|
152
|
+
def bond():
|
|
153
|
+
# Bond/Stretch
|
|
154
|
+
U = M.position_wrt(N)
|
|
155
|
+
q_b = U.magnitude()
|
|
156
|
+
dx_b = (m0, m1, m2, n0, n1, n2)
|
|
157
|
+
args_b = "m0, m1, m2, n0, n1, n2"
|
|
158
|
+
func_result_b = make_deriv_funcs(
|
|
159
|
+
q_b,
|
|
160
|
+
dx_b,
|
|
161
|
+
args_b,
|
|
162
|
+
("q_b", "dq_b", "d2q_b"),
|
|
163
|
+
"Stretch",
|
|
164
|
+
use_mpmath=use_mpmath,
|
|
165
|
+
)
|
|
166
|
+
return func_result_b
|
|
167
|
+
|
|
168
|
+
def bend():
|
|
169
|
+
# Bend/Angle
|
|
170
|
+
U = M.position_wrt(O)
|
|
171
|
+
V = N.position_wrt(O)
|
|
172
|
+
q_a = sym.acos(U.dot(V) / (U.magnitude() * V.magnitude()))
|
|
173
|
+
dx_a = (m0, m1, m2, o0, o1, o2, n0, n1, n2)
|
|
174
|
+
args_a = "m0, m1, m2, o0, o1, o2, n0, n1, n2"
|
|
175
|
+
func_result_a = make_deriv_funcs(
|
|
176
|
+
q_a,
|
|
177
|
+
dx_a,
|
|
178
|
+
args_a,
|
|
179
|
+
("q_a", "dq_a", "d2q_a"),
|
|
180
|
+
"Bend",
|
|
181
|
+
use_mpmath=use_mpmath,
|
|
182
|
+
)
|
|
183
|
+
return func_result_a
|
|
184
|
+
|
|
185
|
+
def bend2():
|
|
186
|
+
# atan2 based Bend/Angle
|
|
187
|
+
U = M.position_wrt(O)
|
|
188
|
+
V = N.position_wrt(O)
|
|
189
|
+
q_a2 = sym.atan2(U.cross(V).magnitude(), U.dot(V))
|
|
190
|
+
dx_a2 = (m0, m1, m2, o0, o1, o2, n0, n1, n2)
|
|
191
|
+
args_a2 = "m0, m1, m2, o0, o1, o2, n0, n1, n2"
|
|
192
|
+
func_result_a = make_deriv_funcs(
|
|
193
|
+
q_a2,
|
|
194
|
+
dx_a2,
|
|
195
|
+
args_a2,
|
|
196
|
+
("q_a2", "dq_a2", "d2q_a2"),
|
|
197
|
+
"Bend2",
|
|
198
|
+
use_mpmath=use_mpmath,
|
|
199
|
+
)
|
|
200
|
+
return func_result_a
|
|
201
|
+
|
|
202
|
+
def dihedral():
|
|
203
|
+
# Dihedral/Torsion
|
|
204
|
+
U = M.position_wrt(O)
|
|
205
|
+
W = P.position_wrt(O)
|
|
206
|
+
V = N.position_wrt(P)
|
|
207
|
+
U_ = U.normalize()
|
|
208
|
+
W_ = W.normalize()
|
|
209
|
+
V_ = V.normalize()
|
|
210
|
+
phi_u = sym.acos(U_.dot(W_))
|
|
211
|
+
phi_v = sym.acos(-W_.dot(V_))
|
|
212
|
+
q_d = sym.acos(
|
|
213
|
+
U_.cross(W_).dot(V_.cross(W_)) / (sym.sin(phi_u) * sym.sin(phi_v))
|
|
214
|
+
)
|
|
215
|
+
dx_d = (m0, m1, m2, o0, o1, o2, p0, p1, p2, n0, n1, n2)
|
|
216
|
+
args_d = "m0, m1, m2, o0, o1, o2, p0, p1, p2, n0, n1, n2"
|
|
217
|
+
func_result_d = make_deriv_funcs(
|
|
218
|
+
q_d,
|
|
219
|
+
dx_d,
|
|
220
|
+
args_d,
|
|
221
|
+
("q_d", "dq_d", "d2q_d"),
|
|
222
|
+
"Torsion",
|
|
223
|
+
use_mpmath=use_mpmath,
|
|
224
|
+
)
|
|
225
|
+
return func_result_d
|
|
226
|
+
|
|
227
|
+
def dihedral2():
|
|
228
|
+
# atan2 based Dihedral/Torsion
|
|
229
|
+
U1 = O.position_wrt(M)
|
|
230
|
+
U2 = P.position_wrt(O)
|
|
231
|
+
U3 = N.position_wrt(P)
|
|
232
|
+
cross_U2U3 = U2.cross(U3)
|
|
233
|
+
q_d2 = sym.atan2(
|
|
234
|
+
(U2.magnitude() * U1).dot(cross_U2U3), cross_U2U3.dot(U1.cross(U2))
|
|
235
|
+
)
|
|
236
|
+
dx_d2 = (m0, m1, m2, o0, o1, o2, p0, p1, p2, n0, n1, n2)
|
|
237
|
+
args_d2 = "m0, m1, m2, o0, o1, o2, p0, p1, p2, n0, n1, n2"
|
|
238
|
+
func_result_d = make_deriv_funcs(
|
|
239
|
+
q_d2,
|
|
240
|
+
dx_d2,
|
|
241
|
+
args_d2,
|
|
242
|
+
("q_d2", "dq_d2", "d2q_d2"),
|
|
243
|
+
"Torsion2",
|
|
244
|
+
use_mpmath=use_mpmath,
|
|
245
|
+
)
|
|
246
|
+
return func_result_d
|
|
247
|
+
|
|
248
|
+
def robust_dihedral1():
|
|
249
|
+
# First component of robust dihedral
|
|
250
|
+
# See Eq. (3.1) in [3]
|
|
251
|
+
U = M.position_wrt(O)
|
|
252
|
+
V = N.position_wrt(P)
|
|
253
|
+
U_ = U.normalize()
|
|
254
|
+
V_ = V.normalize()
|
|
255
|
+
q_rd1 = U_.dot(V_)
|
|
256
|
+
dx_rd1 = (m0, m1, m2, o0, o1, o2, p0, p1, p2, n0, n1, n2)
|
|
257
|
+
args_rd1 = "m0, m1, m2, o0, o1, o2, p0, p1, p2, n0, n1, n2"
|
|
258
|
+
func_result_rd1 = make_deriv_funcs(
|
|
259
|
+
q_rd1,
|
|
260
|
+
dx_rd1,
|
|
261
|
+
args_rd1,
|
|
262
|
+
("q_rd1", "dq_rd1", "d2q_rd1"),
|
|
263
|
+
"RobustTorsion1",
|
|
264
|
+
use_mpmath=use_mpmath,
|
|
265
|
+
)
|
|
266
|
+
return func_result_rd1
|
|
267
|
+
|
|
268
|
+
def robust_dihedral2():
|
|
269
|
+
# Second component of robust dihedral
|
|
270
|
+
# See Eq. (3.2) in [3]
|
|
271
|
+
U = M.position_wrt(O)
|
|
272
|
+
W = P.position_wrt(O)
|
|
273
|
+
V = N.position_wrt(P)
|
|
274
|
+
U_ = U.normalize()
|
|
275
|
+
W_ = W.normalize()
|
|
276
|
+
V_ = V.normalize()
|
|
277
|
+
q_rd2 = W_.dot(U_.cross(V_))
|
|
278
|
+
dx_rd2 = (m0, m1, m2, o0, o1, o2, p0, p1, p2, n0, n1, n2)
|
|
279
|
+
args_rd2 = "m0, m1, m2, o0, o1, o2, p0, p1, p2, n0, n1, n2"
|
|
280
|
+
func_result_rd2 = make_deriv_funcs(
|
|
281
|
+
q_rd2,
|
|
282
|
+
dx_rd2,
|
|
283
|
+
args_rd2,
|
|
284
|
+
("q_rd2", "dq_rd2", "d2q_rd2"),
|
|
285
|
+
"RobustTorsion2",
|
|
286
|
+
use_mpmath=use_mpmath,
|
|
287
|
+
)
|
|
288
|
+
return func_result_rd2
|
|
289
|
+
|
|
290
|
+
def linear_bend():
|
|
291
|
+
# Linear Bend
|
|
292
|
+
U = M.position_wrt(O)
|
|
293
|
+
V = N.position_wrt(O)
|
|
294
|
+
W = P.position_wrt(Sys)
|
|
295
|
+
q_lb = W.dot(U.cross(V)) / (U.magnitude() * V.magnitude())
|
|
296
|
+
dx_lb = (m0, m1, m2, o0, o1, o2, n0, n1, n2)
|
|
297
|
+
# Additional args, as we also supply an orthogonal direction
|
|
298
|
+
args_lb = "m0, m1, m2, o0, o1, o2, n0, n1, n2, p0, p1, p2"
|
|
299
|
+
func_result_lb = make_deriv_funcs(
|
|
300
|
+
q_lb,
|
|
301
|
+
dx_lb,
|
|
302
|
+
args_lb,
|
|
303
|
+
("q_lb", "dq_lb", "d2q_lb"),
|
|
304
|
+
"Linear Bend",
|
|
305
|
+
use_mpmath=use_mpmath,
|
|
306
|
+
)
|
|
307
|
+
return func_result_lb
|
|
308
|
+
|
|
309
|
+
def out_of_plane():
|
|
310
|
+
U = M.position_wrt(P)
|
|
311
|
+
V = N.position_wrt(P)
|
|
312
|
+
W = O.position_wrt(P)
|
|
313
|
+
|
|
314
|
+
U_ = U.normalize()
|
|
315
|
+
W_ = W.normalize()
|
|
316
|
+
V_ = V.normalize()
|
|
317
|
+
|
|
318
|
+
Z = U_.cross(V_) + V_.cross(W_) + W_.cross(U_)
|
|
319
|
+
Z_ = Z.normalize()
|
|
320
|
+
|
|
321
|
+
q_oop = Z_.dot(U_)
|
|
322
|
+
|
|
323
|
+
dx_oop = (m0, m1, m2, n0, n1, n2, o0, o1, o2, p0, p1, p2)
|
|
324
|
+
args_oop = "m0, m1, m2, n0, n1, n2, o0, o1, o2, p0, p1, p2"
|
|
325
|
+
func_result_oop = make_deriv_funcs(
|
|
326
|
+
q_oop,
|
|
327
|
+
dx_oop,
|
|
328
|
+
args_oop,
|
|
329
|
+
("q_oop", "dq_oop", "d2q_oop"),
|
|
330
|
+
"OutOfPlane",
|
|
331
|
+
use_mpmath=use_mpmath,
|
|
332
|
+
)
|
|
333
|
+
return func_result_oop
|
|
334
|
+
|
|
335
|
+
def linear_displacement():
|
|
336
|
+
U = M.position_wrt(O)
|
|
337
|
+
V = N.position_wrt(O)
|
|
338
|
+
W = N.position_wrt(M)
|
|
339
|
+
U_ = U.normalize()
|
|
340
|
+
V_ = V.normalize()
|
|
341
|
+
W_ = W.normalize()
|
|
342
|
+
|
|
343
|
+
# Vector for cross product. For the complement X should correspond
|
|
344
|
+
# to the first orthogonal direction (X = W_.cross(X)).
|
|
345
|
+
X = P.position_wrt(Sys)
|
|
346
|
+
# Orthogonal direction
|
|
347
|
+
Y = W_.cross(X)
|
|
348
|
+
Y_ = Y.normalize()
|
|
349
|
+
|
|
350
|
+
q_ld = Y_.dot(U_) + Y_.dot(V_)
|
|
351
|
+
dx_ld = (m0, m1, m2, o0, o1, o2, n0, n1, n2)
|
|
352
|
+
# Additional args, as we also supply an orthogonal direction
|
|
353
|
+
args_ld = "m0, m1, m2, o0, o1, o2, n0, n1, n2, p0, p1, p2"
|
|
354
|
+
func_result_ld = make_deriv_funcs(
|
|
355
|
+
q_ld,
|
|
356
|
+
dx_ld,
|
|
357
|
+
args_ld,
|
|
358
|
+
("q_ld", "dq_ld", "d2q_ld"),
|
|
359
|
+
"Linear Displacement",
|
|
360
|
+
use_mpmath=use_mpmath,
|
|
361
|
+
)
|
|
362
|
+
return func_result_ld
|
|
363
|
+
|
|
364
|
+
if generate is None:
|
|
365
|
+
generate = (
|
|
366
|
+
"bond",
|
|
367
|
+
"bend",
|
|
368
|
+
"bend2",
|
|
369
|
+
"dihedral",
|
|
370
|
+
"dihedral2",
|
|
371
|
+
"robust_dihedral1",
|
|
372
|
+
"robust_dihedral2",
|
|
373
|
+
"linear_bend",
|
|
374
|
+
"out_of_plane",
|
|
375
|
+
"linear_displacement",
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
avail_funcs = {
|
|
379
|
+
"bond": bond,
|
|
380
|
+
"bend": bend,
|
|
381
|
+
"bend2": bend2,
|
|
382
|
+
"dihedral": dihedral,
|
|
383
|
+
"dihedral2": dihedral2,
|
|
384
|
+
"robust_dihedral1": robust_dihedral1,
|
|
385
|
+
"robust_dihedral2": robust_dihedral2,
|
|
386
|
+
"linear_bend": linear_bend,
|
|
387
|
+
"out_of_plane": out_of_plane,
|
|
388
|
+
"linear_displacement": linear_displacement,
|
|
389
|
+
}
|
|
390
|
+
funcs = [avail_funcs[key] for key in generate]
|
|
391
|
+
func_results = list()
|
|
392
|
+
for name, func in zip(generate, funcs):
|
|
393
|
+
print(f"Generating expressions for: '{name}'")
|
|
394
|
+
func_res = func()
|
|
395
|
+
func_results.append(func_res)
|
|
396
|
+
|
|
397
|
+
import_str = "import mpmath" if use_mpmath else "import math"
|
|
398
|
+
if out_fn:
|
|
399
|
+
with open(out_fn, "w") as handle:
|
|
400
|
+
handle.write(f"{import_str}\n\nimport numpy as np\n\n\n")
|
|
401
|
+
for fr in func_results:
|
|
402
|
+
handle.write(fr.f0 + "\n\n\n")
|
|
403
|
+
handle.write(fr.f1 + "\n\n\n")
|
|
404
|
+
handle.write(fr.f2 + "\n\n\n")
|
|
405
|
+
print(f"Wrote generated code to '{out_fn}'")
|
|
406
|
+
|
|
407
|
+
return func_results
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
if __name__ == "__main__":
|
|
411
|
+
generate_wilson(out_fn="derivatives.py", use_mpmath=False)
|
|
412
|
+
# print()
|
|
413
|
+
generate_wilson(out_fn="mp_derivatives.py", use_mpmath=True)
|
|
414
|
+
# generate_wilson(out_fn="lindisp.py", use_mpmath=False)
|