Hybrid Eigenvector Following
The single_ended_search module contains methods for locating transition states starting from a single point
- class topsearch.transition_states.hybrid_eigenvector_following.HybridEigenvectorFollowing(potential: Potential, ts_conv_crit: float, ts_steps: int, pushoff: float, steepest_descent_conv_crit: float = 1e-06, min_uphill_step_size: float = 1e-07, max_uphill_step_size: float = 1.0, positive_eigenvalue_step: float = 0.1, eigenvalue_conv_crit: float = 1e-05, output_level: int = 0, tag: str = '')
Description
Class for single-ended transition state searches. Starting from a given position the hybrid eigenvector-following algorithm (https://doi.org/10.1103/PhysRevB.59.3969) is used to take steps uphill until a Hessian index one point is found. i) Finds eigenvector corresponding to the lowest eigenvalue ii) Take a step along that eigenvector iii) Minimise in the remaining subspace iv) Repeat until convergence
- potential
Function on which we are attempting to find transition states
- Type:
class instance
- conv_crit
The value the norm of the gradient must be less than before the transition state is considered converged
- Type:
float
- ts_steps
Allowed number of steps before giving up on transition state
- Type:
int
- max_uphill_step_size
Maximum size of a step that goes in the uphill direction following the eigenvector corresponding to the negative eigenvalue
- Type:
float
- positive_eigenvalue_step
The size of a step along the eigenvector corresponding to the smallest eigenvalue, when it is still positive
- Type:
float
- pushoff
The size of the displacement along the eigenvector when finding connected minima for each transition state
- Type:
float
- eig_bounds
Bounds placed on the eigenvector during minimisation, updated throughout the search based on active bounds
- Type:
list
- failure
Contains the reason for failure to find a transition state to report
- Type:
string
- remove_trans_rot
Flag as to whether to remove eigenvectors that correspond to overall translation and rotation, needed for atomic and molecular systems
- Type:
bool
- analytic_step_size(grad: NDArray[Any, Any], eigenvector: NDArray[Any, Any], eigenvalue: float) float
Analytical expression to compute an optimal step length from coords along eigenvector, given its eigenvalue. Return the appropriate step length in the uphill direction
- check_eigenvector_direction(eigenvector: NDArray[Any, Any], position: NDArray[Any, Any]) NDArray[Any, Any]
Check the eigenvector is pointing in the uphill direction, and if not, flip it so it is
- check_valid_eigenvector(eigenvector: NDArray[Any, Any], eigenvalue: float, coords: StandardCoordinates) bool
Test that an eigenvector is valid. It cannot contain only zeros or any nans
- do_pushoff(ts_position: StandardCoordinates, eigenvector: NDArray[Any, Any], increment: float, iteration: int) NDArray[Any, Any]
Take a step along the pushoff. Return the new position after performing pushoff
- find_pushoff(transition_state: StandardCoordinates, eigenvector: NDArray[Any, Any]) tuple[NDArray[Any, Any], NDArray[Any, Any]]
Given the transition state location and direction of its single negative eigenvalue. We compute a step length in this direction before beginning a steepest-descent path. Returns the points to begin steepest-descent paths in the forwards and backwards direction
- generate_random_vector(ndim: int) NDArray[Any, Any]
Return random uniform vector on sphere
- get_local_bounds(coords: StandardCoordinates) list
Create a box around the given point that ensures that subspace minimisation is bounded to a small region to avoid moving to a different basin. Still respect total function bounds
- get_smallest_eigenvector(initial_vector: NDArray[Any, Any], coords: StandardCoordinates, lower_bounds: NDArray[Any, Any], upper_bounds: NDArray[Any, Any]) NDArray[Any, Any]
Routine to find the smallest eigenvalue and the associated eigenvector of the Hessian at a given point coords. Method tests for validity and deals with bounds
- parallel_component(vec1: NDArray[Any, Any], vec2: NDArray[Any, Any]) NDArray[Any, Any]
Return parallel component of vec1 relative to vec2
- perpendicular_component(vec1: NDArray[Any, Any], vec2: NDArray[Any, Any]) NDArray[Any, Any]
Return perpendicular component of vector vec1 relative to vec2
- project_onto_bounds(vector: NDArray[Any, Any], lower_bounds: NDArray[Any, Any], upper_bounds: NDArray[Any, Any]) NDArray[Any, Any]
Project vector back to within the bounds if pointing outside
- rayleigh_ritz_function_gradient(vec: NDArray[Any, Any], *args: list) tuple[float, NDArray[Any, Any]]
Evaluate the Rayleigh-Ritz ratio to find the value of the eigenvalue for a given eigenvector vec computed at point coords, and the gradient with respect to changes in vec
- remove_zero_eigenvectors(vec: NDArray[Any, Any], position: NDArray[Any, Any]) NDArray[Any, Any]
Make vec orthogonal to eigenvectors of the Hessian corresponding to overall translations and rotations at given position
- run(coords: StandardCoordinates, tag: str = '') tuple
Perform a single-ended transition state search starting from coords. Returns the information about transition states and their connected minima that is needed for testing similarity and adding to stationary point network
- steepest_descent(transition_state: StandardCoordinates, eigenvector: NDArray[Any, Any]) tuple
Perturb away from the transition state along the eigenvector corresponding to the negative eigenvalue and minimise to produce the two connected minima and their energies Returns the coordinates and energy of both connected minima
- steepest_descent_paths(coords: StandardCoordinates) tuple
Perform local minimisation to get the result of a steepest descent path beginning from position. To avoid very large initial steps in LBFGS we constrain the local minimisation into several short steps
- subspace_function_gradient(position: NDArray[Any, Any], *args: list) tuple[float, NDArray[Any, Any]]
Return the function value and the component of the gradient perpendicular to self.eigenvector at point coords
- subspace_minimisation(coords: StandardCoordinates, eigenvector: NDArray[Any, Any]) tuple
Perform minimisation in the subspace orthogonal to eigenvector. The distance is limited to be at most 2% of the range of the space to avoid very large initial steps in scipy.lbfgs
- take_uphill_step(coords: StandardCoordinates, eigenvector: NDArray[Any, Any], eigenvalue: float) NDArray[Any, Any]
Take uphill step of appropriate length given an eigenvector that defines the step direction, and an eigenvalue that determines if the step is uphill or not. Return coords after step is taken
- test_convergence(position: NDArray[Any, Any], lower_bounds: NDArray[Any, Any], upper_bounds: NDArray[Any, Any]) bool
Test for convergence accounting for active bounds. Only consider the gradient components in dimensions not at bounds. Return True if points passes convergence test
- update_eigenvector_bounds(lower_bounds: NDArray[Any, Any], upper_bounds: NDArray[Any, Any]) None
Update the bounds on eigenvector to ensure it remains in certain portion of the sphere that points within the function bounds