stko.GulpUFFOptimizer

class stko.GulpUFFOptimizer(gulp_path, maxcyc=1000, metal_FF=None, metal_ligand_bond_order=None, conjugate_gradient=False, output_dir=None)[source]

Bases: Optimizer

Applies forcefield optimizers that can handle metal centres.

Parameters:
  • gulp_path (Path | str) – Path to GULP executable.

  • maxcyc (int) – Set the maximum number of optimisation steps to use. Default in Gulp is 1000.

  • metal_FF (dict | None) – Dictionary with metal atom forcefield assignments. Key: int : atomic number. Value: str : UFF4MOF forcefield type.

  • metal_ligand_bond_order (str | None) – Bond order to use for metal-ligand bonds. Defaults to half, but using resonant can increase the force constant for stronger metal-ligand interactions.

  • conjugate_gradient (bool) – True to use Conjugate Graditent method. Defaults to False

  • output_dir (Path | str | None) – The name of the directory into which files generated during the calculation are written, if None then uuid.uuid4() is used.

Notes

By default, optimize() will run an optimisation using the UFF4MOF. This forcefield requires some explicit metal atom definitions, which are determined by the user.

This code was originally written for use with Gulp 5.1 on Linux and has not been officially tested on other versions and operating systems. Make sure to sanity check the output.

Examples

While metal atoms are not required, UFF4MOF is useful because it encompasses almost all chemical environments commonly found in metal-organic structures. Better forcefields exist for purely organic molecules! An interface with GULP is provided, which takes the forcefield types assigned by RDKit for non-metal atoms and user defined forcefield types for metal atoms to perform geometry optimisations.

import stk
import stko
from rdkit.Chem import AllChem as rdkit

# Produce a Pd+2 atom with 4 functional groups.
atom = rdkit.MolFromSmiles('[Pd+2]')
atom.AddConformer(rdkit.Conformer(atom.GetNumAtoms()))
palladium_atom = stk.BuildingBlock.init_from_rdkit_mol(atom)
atom_0, = palladium_atom.get_atoms(0)
palladium_atom = palladium_atom.with_functional_groups(
    (stk.SingleAtom(atom_0) for i in range(4))
)

# Build a building block with two functional groups using
# the SmartsFunctionalGroupFactory.
bb1 = stk.BuildingBlock(
    smiles=('C1=CC(=CC(=C1)C2=CN=CC=C2)C3=CN=CC=C3'),
    functional_groups=[
        stk.SmartsFunctionalGroupFactory(
            smarts='[#6]~[#7X2]~[#6]',
            bonders=(1, ),
            deleters=(),
        ),
    ],
)

# Build a metal-organic cage with dative bonds between
# GenericFunctionalGroup and SingleAtom functional groups.
cage = stk.ConstructedMolecule(
    stk.cage.M2L4Lantern(
        building_blocks={
            palladium_atom: (0, 1),
            bb1: (2, 3, 4, 5)
        },
        reaction_factory=stk.DativeReactionFactory(
            stk.GenericReactionFactory(
                bond_orders={
                    frozenset({
                        stk.GenericFunctionalGroup,
                        stk.SingleAtom
                    }): 9
                }
            )
        )
    )
)

# Perform Gulp optimisation with UFF4MOF.
# Use conjugate gradient method for a slower, but more stable
# optimisation.

gulp_opt = stko.GulpUFFOptimizer(
    gulp_path='path/to/gulp',
    metal_FF={46: 'Pd4+2'},
    conjugate_gradient=True
)

# Assign the force field.
gulp_opt.assign_FF(cage)
# Run optimization.
cage = gulp_opt.optimize(mol=cage)

Methods

assign_FF

Assign forcefield types to molecule.

extract_final_energy

optimize

Optimize mol.

p_optimize

Optimize mol and unit_cell.

assign_FF(mol)[source]

Assign forcefield types to molecule.

Parameters:

mol (Molecule) – The molecule to be optimized.

Return type:

None

extract_final_energy(out_file)[source]
Parameters:

out_file (Path)

Return type:

float

optimize(mol)[source]

Optimize mol.

Parameters:

mol (MoleculeT) – The molecule to be optimized.

Returns:

The optimized molecule.

Return type:

MoleculeT

p_optimize(mol, unit_cell)[source]

Optimize mol and unit_cell.

Parameters:
  • mol (MoleculeT) – The molecule to be optimized.

  • unit_cell (UnitCell) – The unit_cell to be optimized if optimization is periodic.

Returns:

The optimized molecule and the optimized cell.

Return type:

tuple[MoleculeT, UnitCell]