Source code for stk._internal.optimizers.spinner

import spindry as spd

from stk._internal.construction_state.construction_state import (
    ConstructionState,
)

from .optimizer import Optimizer


[docs] class Spinner(Optimizer): """ Performs Monte Carlo optimisation of host-guest complexes. Examples: *Structure Optimization* Using :class:`.Spinner` will lead to :class:`.ConstructedMolecule` structures with better host-guest structures. Especially useful for multiple-guest systems and removing overlap. .. testcode:: structure-optimization import stk bb1 = stk.BuildingBlock( smiles='NCCN', functional_groups=[stk.PrimaryAminoFactory()], ) bb2 = stk.BuildingBlock( smiles='O=CC(C=O)C=O', functional_groups=[stk.AldehydeFactory()], ) guest1 = stk.host_guest.Guest( building_block=stk.BuildingBlock('c1ccccc1'), ) guest2 = stk.host_guest.Guest( building_block=stk.BuildingBlock('C1CCCCC1'), ) cage = stk.ConstructedMolecule( topology_graph=stk.cage.FourPlusSix( building_blocks=(bb1, bb2), optimizer=stk.MCHammer(), ), ) complex = stk.ConstructedMolecule( topology_graph=stk.host_guest.Complex( host=stk.BuildingBlock.init_from_molecule(cage), guests=(guest1, guest2), optimizer=stk.Spinner(), ), ) Optimisation with :mod:`stk` simply collects the final position matrix. The optimisation's trajectory can be output using the :mod:`SpinDry` implementation if required by the user [#spindry]_. This code is entirely nonphysical and is, therefore, completely general to any chemistry. References: .. [#spindry] https://github.com/andrewtarzia/SpinDry """ def __init__( self, step_size: float = 1.5, rotation_step_size: float = 5.0, num_conformers: int = 50, max_attempts: int = 1000, nonbond_epsilon: float = 5.0, beta: float = 2.0, random_seed: int = 1000, ) -> None: """ Initialize an instance of :class:`.Spinner`. Parameters: step_size: The relative size of the step to take during step. rotation_step_size: The relative size of the rotation to take during step. num_conformers: Number of conformers to extract. max_attempts: Maximum number of MC moves to try to generate conformers. nonbond_epsilon: Value of epsilon used in the nonbonded potential in MC moves. Determines strength of the nonbonded potential. beta: Value of beta used in the in MC moves. Beta takes the place of the inverse boltzmann temperature. random_seed: Random seed to use for MC algorithm. """ self._optimizer = spd.Spinner( step_size=step_size, rotation_step_size=rotation_step_size, num_conformers=num_conformers, max_attempts=max_attempts, potential_function=spd.SpdPotential( nonbond_epsilon=nonbond_epsilon, ), beta=beta, random_seed=random_seed, )
[docs] def optimize(self, state: ConstructionState) -> ConstructionState: supramolecule = spd.SupraMolecule( atoms=( spd.Atom( id=atom.get_id(), element_string=atom.__class__.__name__, ) for atom in state.get_atoms() ), bonds=( spd.Bond( id=i, atom_ids=( bond.get_atom1().get_id(), bond.get_atom2().get_id(), ), ) for i, bond in enumerate(state.get_bonds()) ), position_matrix=state.get_position_matrix(), ) conformer = self._optimizer.get_final_conformer(supramolecule) return state.with_position_matrix( position_matrix=conformer.get_position_matrix(), )