Source code for pysisyphus.cos.GrowingChainOfStates

import numpy as np

from pysisyphus.cos.ChainOfStates import ChainOfStates
from pysisyphus.Geometry import Geometry


[docs] class GrowingChainOfStates(ChainOfStates): def __init__(self, images, calc_getter, max_nodes=10, **kwargs): super().__init__(images, **kwargs) self.max_nodes = max_nodes self.calc_getter = calc_getter self.zero_step = np.zeros_like(self.images[0].coords)
[docs] def get_new_image_from_coords(self, coords, index): new_image = Geometry( self.image_atoms, coords, coord_type=self.coord_type, coord_kwargs={"typed_prims": self.typed_prims}, ) new_image.set_calculator(self.calc_getter()) self.images.insert(index, new_image) self.log(f"Create new image; insert it before index {index}.") return new_image
@property def arc_dims(self): cds = [ 0, ] for i, image in enumerate(self.images[:-1]): next_image = self.images[i + 1] diff = np.linalg.norm(next_image - image) cds.append(diff) cds = np.cumsum(cds) tot_length = cds[-1] norm_cds = cds / cds.max() return tot_length, norm_cds @property def max_image_num(self): return self.max_nodes + 2
[docs] def new_node_coords(self, k): l = (self.max_nodes - k) / (self.max_nodes + 1 - k) kth_coords = self.images[k].coords last_coords = self.images[-1].coords new_coords = l * kth_coords + (1 - l) * last_coords return new_coords
[docs] def set_new_node(self, k): new_coords = self.new_node_coords(k) new_node = Geometry(self.image_atoms, new_coords) new_node.set_calculator(self.calc_getter()) self.images.insert(k + 1, new_node) return new_node
[docs] def prepare_opt_cycle(self, *args, **kwargs): parent_result, parent_messages = super().prepare_opt_cycle(*args, **kwargs) # Compare size of coords arrays to determine if new nodes # were added in the last reparametrization. last_size = self.coords_list[-1].size length_changed = last_size != self.coords.size reset_flag = parent_result or length_changed return reset_flag, parent_messages
[docs] def propagate(self, force_unique_overlap_data_fns=True): # As the COS is not fully grown at the beginning calculating overlaps # between both sides of the COS may be difficult/impossible. # A way in supporting this for double-sided COS calucaltions may be to ask # the user for a second root that is used for the final image in the COS, # which is then propagated "inwards". raise Exception( "propagate() is not yet implemented for growing Chain-Of-States!" )