Beispiel #1
0
 def test_replace_outoflimits(self):
     ''' Must leave current image unchanged if it tries to replace an non existing image'''
     chain.replace_image( self.p_state, idx_image=5 )        # replace 0th with 5th (not exist)
     self.assertEqual( system.get_index( self.p_state ), 0 ) # active is 0th
     self.assertEqual( chain.get_noi( self.p_state ), 1 )    # total 1 image
     chain.replace_image( self.p_state, idx_image=-5 )       # replace 0th with -5th (not exist)
     self.assertEqual( system.get_index( self.p_state ), 0 ) # active is 0th
     self.assertEqual( chain.get_noi( self.p_state ), 1 )    # total 1 image
Beispiel #2
0
 def test_delete_outoflimits(self):
     
     chain.insert_image_before( self.p_state )               # active is 1st
     chain.insert_image_before( self.p_state )               # active is 2nd
     self.assertEqual( system.get_index( self.p_state ), 2 ) # active is 2nd
     self.assertEqual( chain.get_noi( self.p_state ), 3 )    # total 3 images
     
     # test the deletion of a non existing image with positive idx
     chain.delete_image( self.p_state, idx_image=5 )         # delete -5th (not exist)
     self.assertEqual( chain.get_noi( self.p_state ), 3 )    # total 3 images
     
     # test the deletion of a non existing image with negative idx
     chain.delete_image( self.p_state, idx_image=-5 )        # delete -5th (not exist)
     self.assertEqual( chain.get_noi( self.p_state ), 2 )    # total 2 images
     self.assertEqual( system.get_index( self.p_state ), 1 ) # active is 1st
        def helper(p_state, node):
            node.log("    collecting...")
            # Make sure the number of images matches our current simulation state
            chain.image_to_clipboard(p_state)
            noi = io.n_images_in_file(p_state, node.chain_file)
            chain.set_length(p_state, noi)
            io.chain_read(p_state, node.chain_file)
            noi = chain.get_noi(p_state)

            i = 0
            while i < noi:
                # First we check if this images is within any of the ranges covered by the children
                is_child = False
                for idx_c, (i1, i2) in enumerate(node.child_indices):
                    if i >= i1 and i <= i2:
                        is_child = True
                        idx_child = idx_c
                        break

                # If the current idx is covered by a child node, we open up another level of recursion, else we append the image
                if is_child:
                    helper(p_state, node.children[idx_child])
                    # After collecting the child we advance the current iteration idx, so that we continue one past the last child index
                    i = node.child_indices[idx_child][1] + 1
                    # We also need to read the chain file again to return to our previous state
                    chain.image_to_clipboard(p_state)
                    chain.set_length(p_state, noi)
                    io.chain_read(p_state, node.chain_file)
                else:
                    io.image_append(p_state, output_file, idx_image=i)
                    i += 1
    def spawn_children(self, p_state):
        """If intermediate minima are present, relaxes them and creates child nodes"""

        from spirit import chain, simulation

        if not self.allow_split:
            return

        if len(self.intermediate_minima) == 0:
            return

        if self._converged:
            return

        self.log("Spawning children - splitting chain")

        self.log("Relaxing intermediate minima")
        for idx_minimum in self.intermediate_minima:
            simulation.start(p_state,
                             simulation.METHOD_LLG,
                             self.solver_llg,
                             idx_image=idx_minimum)

        # Instantiate the GNEB nodes
        noi = chain.get_noi(p_state)
        # Creates a list of all indices that would be start/end points of new chains
        idx_list = [0, *self.intermediate_minima, noi - 1]
        # From the previous list, creates a list of pairs of start/end points
        idx_pairs = [(idx_list[i], idx_list[i + 1])
                     for i in range(len(idx_list) - 1)]

        # First create all the instances of GNEB nodes
        for i1, i2 in idx_pairs:
            self.add_child(i1, i2, p_state)
Beispiel #5
0
 def test_pop_back(self):
     ''' Must make the image with next smaller index active when the active is poped'''
     chain.insert_image_before( self.p_state )               # add before active
     self.assertEqual( system.get_index( self.p_state ), 1 ) # active is 1st
     chain.pop_back( self.p_state )                          # delete the last (active)
     self.assertEqual( system.get_index( self.p_state ), 0 ) # active is 0th
     self.assertEqual( chain.get_noi( self.p_state ), 1 )    # total 1 image
    def prepare_moving_endpoints(self, idx_mid=-1):
        from spirit import chain, io, state, parameters

        self.log("Preparing for moving endpoints")

        self.target_noi = 3
        self.moving_endpoints = True
        self.image_types = [[1, parameters.gneb.IMAGE_CLIMBING]]

        with state.State(self.input_file) as p_state:
            self._prepare_state(p_state)
            self.update_energy_path(p_state)

            noi = chain.get_noi(p_state)

            if idx_mid < 0:
                E = chain.get_energy(p_state)
                idx_mid = np.argmax(E)

            self.log("idx_mid = {}".format(idx_mid))

            if (idx_mid >= 1 and idx_mid < noi - 1):
                for i in range(idx_mid - 1):
                    chain.delete_image(p_state, idx_image=0)
                for i in range(noi - idx_mid - 2):
                    chain.pop_back(p_state)

            self.update_energy_path(p_state)
            self.save_chain(p_state)
 def mark_climbing_image(p_state, gnw, ax):
     """Helper function that marks the climbing image in a plot."""
     import numpy as np
     image_types = np.array([
         gneb.get_climbing_falling(p_state, i)
         for i in range(chain.get_noi(p_state))
     ])
     idx_climbing_list = np.array(range(
         chain.get_noi(p_state)))[image_types == gneb.IMAGE_CLIMBING]
     if (len(idx_climbing_list) == 0):
         return
     idx_climbing = idx_climbing_list[0]
     E0 = gnw.current_energy_path.total_energy[-1]
     ax.plot(gnw.current_energy_path.reaction_coordinate[idx_climbing],
             gnw.current_energy_path.total_energy[idx_climbing] - E0,
             marker="^",
             color="red")
def chain_append_from_file(p_state, filename):
    # TODO: chain_read with insert_idx seems to be broken
    raise NotImplementedError()
    from spirit import io, chain
    noi_file = io.n_images_in_file(p_state, filename)
    noi = chain.get_noi(p_state)
    chain.image_to_clipboard(p_state)
    chain.set_length(p_state, noi + noi_file)
    io.chain_read(p_state, filename, insert_idx=noi)
    chain.update_data(p_state)
    def increase_noi(self, p_state=None):
        """Increases the noi by (roughly) a factor of two until the number of images is at least as large as target_noi"""
        from spirit import state, chain, transition, io

        with state.State(self.input_file) as p_state:
            self._prepare_state(p_state)
            self.noi = chain.get_noi(p_state)

            if (self.noi < self.target_noi):
                self.log(
                    "Too few images ({}). Inserting additional interpolated images"
                    .format(self.noi))

            while (self.noi < self.target_noi):
                transition.homogeneous_insert_interpolated(p_state, 1)
                self.noi = chain.get_noi(p_state)

            self.log("Number of images = {}".format(self.noi))
            self.save_chain(p_state)
    def chain_rebalance(self, p_state, tol=0.25):
        """Tries to rebalance the chain while keeping the number of images constant. The closer tol is to zero, the more aggressive the rebalancing."""
        import numpy as np
        from spirit import chain, transition
        from spirit.parameters import gneb
        noi = chain.get_noi(p_state)

        idx_max = np.argmax(self.current_energy_path.total_energy)

        delta_Rx = [
            self.current_energy_path.reaction_coordinate[i + 1] -
            self.current_energy_path.reaction_coordinate[i]
            for i in range(noi - 1)
        ]
        delta_Rx_2 = [
            self.current_energy_path.reaction_coordinate[i + 2] -
            self.current_energy_path.reaction_coordinate[i]
            for i in range(noi - 2)
        ]
        max_delta_Rx = np.max(delta_Rx)
        min_delta_Rx2 = np.min(delta_Rx_2)

        if max_delta_Rx > (1 + np.abs(tol)) * min_delta_Rx2:
            self.log("Rebalancing chain")
            self.log("      Max. Delta Rx {}, Min. Delta Rx2 {}".format(
                max_delta_Rx, min_delta_Rx2))
            idx = np.argmax(delta_Rx)
            idx_2 = np.argmin(delta_Rx_2)
            self.log("      Inserting after idx {}, deleting idx {}".format(
                idx, idx_2 + 1))

            # Delete the image that was too densely spaced. this will shift all indices greater than idx_2+1
            chain.delete_image(p_state, idx_image=idx_2 + 1)

            # Correct the index if necessary
            if (idx > idx_2 + 1) < idx:
                idx -= 1

            chain.insert_image_after(p_state, idx)
            transition.homogeneous(p_state, idx, idx + 2)
def chain_write_between(p_state,
                        filename,
                        idx_start,
                        idx_stop,
                        fileformat=None):
    """Writes the chain between idx_start and idx_stop to a file. Includes the endpoints!"""
    from spirit import io, chain

    if fileformat is None:
        fileformat = io.FILEFORMAT_OVF_TEXT

    noi = chain.get_noi(p_state)

    if (idx_start > idx_stop or idx_start < 0 or idx_stop >= noi):
        raise Exception("Error in idx_start and/or idx_stop")

    io.image_write(p_state,
                   filename,
                   idx_image=idx_start,
                   fileformat=fileformat)
    for i in range(idx_start + 1, idx_stop + 1):
        io.image_append(p_state, filename, idx_image=i, fileformat=fileformat)
    def prepare_dimer(self, idx_left, idx_right=None):
        from spirit import chain, io, state, parameters

        if idx_right is None:
            idx_right = idx_left + 1

        self.log("Preparing for dimer endpoints")

        self.target_noi = 2
        self.moving_endpoints = True
        self.translating_endpoints = True
        self.image_types = []

        with state.State(self.input_file) as p_state:
            self._prepare_state(p_state)
            self.update_energy_path(p_state)

            noi = chain.get_noi(p_state)

            self.log("idx_left = {}, idx_right = {}".format(
                idx_left, idx_right))

            # Delete all images to the right of idx right
            for i in range(noi - idx_right - 1):
                chain.pop_back(p_state)

            # Delete all images to the left of idx_left
            for i in range(idx_left):
                chain.delete_image(p_state, idx_image=0)

            # Delete images between idx_left and idx_right
            for i in range(idx_right - idx_left - 1):
                chain.delete_image(p_state, idx_image=1)

            self.update_energy_path(p_state)
            self.save_chain(p_state)
Beispiel #13
0
 def test_push_back(self):
     ''' Must add one image and leave active's index unchanged '''
     chain.push_back( self.p_state )                         # add after all
     self.assertEqual( chain.get_noi( self.p_state ), 2 )    # total 2 images
     self.assertEqual( system.get_index( self.p_state ), 0 ) # active is 0th
Beispiel #14
0
 def test_insert_before(self):
     ''' Must reindex (increment by one) active image '''
     chain.insert_image_before( self.p_state )               # add before active
     self.assertEqual( chain.get_noi( self.p_state ), 2 )    # total 2 images
     self.assertEqual( system.get_index( self.p_state ), 1 ) # active is 1st
Beispiel #15
0
 def test_insert_after(self):
     ''' Must leave the index of active image the same '''
     chain.insert_image_after( self.p_state )                # add after active
     self.assertEqual( chain.get_noi( self.p_state ), 2 )    # total 2 images
     self.assertEqual( system.get_index( self.p_state ), 0 ) # active is 0th
Beispiel #16
0
 def test_NOI(self):
     ''' NOI -> Number of images in that chain '''
     self.assertEqual( chain.get_noi( self.p_state ), 1 )    # total 1 image
Beispiel #17
0
 def tearDown(self):
     ''' clean the p_state '''
     noi = chain.get_noi( self.p_state )
     for i in range(noi-1):
         chain.pop_back( self.p_state )
     self.assertEqual( chain.get_noi( self.p_state ), 1 )
Beispiel #18
0
 def test_remove_smallest_index_active(self):
     '''' Must set the active to the image with the smallest index left'''
     chain.insert_image_after( self.p_state )                # active is 0th
     chain.delete_image( self.p_state )                      # delete 0th
     self.assertEqual( chain.get_noi( self.p_state ), 1 )    # total 1 image
     self.assertEqual( system.get_index( self.p_state ), 0 ) # active is 0th
Beispiel #19
0
 def test_delete_trivial(self):
     ''' Must NOT delete the image of a chain with only one image'''
     chain.delete_image( self.p_state )                      # delete 0th
     self.assertEqual( chain.get_noi( self.p_state ), 1 )    # total 1 image