Exemplo n.º 1
0
def Instanton(x0, f0, f1, h, update, asr, im, gm, big_step, opt, m, omaker):
    """Do one step. Update hessian for the new position. Update the position and force inside the mapper.

       Input:  x0 = last positions
               f0 = last physical forces
               f1 = last spring forces
                h = physical hessian
           update = how to update the hessian
              asr = how to clean the hessian
               im = spring mapper
               gm = gradient  mapper
         big_step = limit on step length
              opt = optimization algorithm to use
              m   = type of calculation: rate or splitting"""

    info(" @Instanton_step", verbosity.high)

    if opt == 'nichols':
        # Construct hessian and get eigenvalues and eigenvector
        h0 = red2comp(h, im.dbeads.nbeads, im.dbeads.natoms)    # construct complete hessian from reduced
        h1 = np.add(im.h, h0)                                 # add spring terms to the physical hessian
        d, w = clean_hessian(h1, im.dbeads.q, im.dbeads.natoms, im.dbeads.nbeads, im.dbeads.m, im.dbeads.m3, asr)

        # Find new movement direction
        if m == 'rate':
            d_x = nichols(f0, f1, d, w, im.dbeads.m3, big_step)
        elif m == 'splitting':
            d_x = nichols(f0, f1, d, w, im.dbeads.m3, big_step, mode=0)

    elif opt == 'NR':
        h_up_band = banded_hessian(h, im)  # create upper band matrix
        f = (f0 + f1).reshape(im.dbeads.natoms * 3 * im.dbeads.nbeads, 1)

        d_x = invmul_banded(h_up_band, f)
        d_x.shape = im.dbeads.q.shape

    # Rescale step
    d_x_max = np.amax(np.absolute(d_x))
    info(" @Instanton: Current step norm = %g" % d_x_max, verbosity.medium)
    if np.amax(np.absolute(d_x)) > big_step:
        info(" @Instanton: Attempted step norm = %g, scaled down to %g" % (d_x_max, big_step), verbosity.low)
        d_x *= big_step / np.amax(np.absolute(d_x_max))

    # Make movement and get new energy (u)  and forces(f) using mapper
    x = x0 + d_x
    im(x, ret=False)  # Only to update the mapper
    u, g2 = gm(x)
    f = -g2

    # Update hessian
    if update == 'powell':
        d_g = np.subtract(f0, f)
        i = im.dbeads.natoms * 3
        for j in range(im.dbeads.nbeads):
            aux = h[:, j * i:(j + 1) * i]
            dg = d_g[j, :]
            dx = d_x[j, :]
            Powell(dx, dg, aux)
    elif update == 'recompute':
        get_hessian(h, gm, x, omaker)
Exemplo n.º 2
0
    def exitstep(self, fx, fx0, x, exitt, step):
        """ Exits the simulation step. Computes time, checks for convergence. """
        self.qtime += time.time()

        #f = open('STEP', 'a+')
        #print >>f, 'STEP %i' % step
        #print >>f, 'Energy difference: %.1e, (condition: %.1e)' % (np.absolute((fx - fx0) / self.beads.natoms), self.tolerances["energy"] )
        #print >>f, 'Maximum force component: %.1e, (condition: %.1e)' % (np.amax(np.absolute(self.forces.f+self.im.f)), self.tolerances["force"])
        #print >>f, 'Maximum component step component: %.1e, (condition: %.1e)' % (x, self.tolerances["position"])
        #print >>f, ' '
        #f.close()

        info(
            ' @Exit step: Energy difference: %.1e, (condition: %.1e)' %
            (np.absolute(
                (fx - fx0) / self.beads.natoms), self.tolerances["energy"]),
            verbosity.low)
        info(
            ' @Exit step: Maximum force component: %.1e, (condition: %.1e)' %
            (np.amax(np.absolute(self.forces.f + self.im.f)),
             self.tolerances["force"]), verbosity.low)
        info(
            ' @Exit step: Maximum component step component: %.1e, (condition: %.1e)'
            % (x, self.tolerances["position"]), verbosity.low)

        if (np.absolute((fx - fx0) / self.beads.natoms) <= self.tolerances["energy"]) \
                and ((np.amax(np.absolute(self.forces.f + self.im.f)) <= self.tolerances["force"]) or
                         (np.linalg.norm(self.forces.f.flatten() - self.old_f.flatten()) <= 1e-08)) \
                and (x <= self.tolerances["position"]):

            print_instanton_geo(self.prefix + '_FINAL', step,
                                self.im.dbeads.nbeads, self.im.dbeads.natoms,
                                self.im.dbeads.names, self.im.dbeads.q,
                                self.old_u, self.cell, self.energy_shift)

            if self.hessian_final != 'true':
                info("We are not going to compute the final hessian.",
                     verbosity.low)
                info(
                    "Warning, The current hessian is not the real hessian is only an approximation .",
                    verbosity.low)

            else:
                info("We are going to compute the final hessian",
                     verbosity.low)
                get_hessian(self.hessian, self.gm, self.im.dbeads.q)
                print_instanton_hess(self.prefix + '_FINAL', step,
                                     self.hessian)

            exitt = True  #If we just exit here, the last step (including the last hessian) will not be in the RESTART file

        return exitt
Exemplo n.º 3
0
    def exitstep(self, fx, fx0, x, exitt, step):
        """ Exits the simulation step. Computes time, checks for convergence. """
        self.qtime += time.time()

        #f = open('STEP', 'a+')
        #print >>f, 'STEP %i' % step
        #print >>f, 'Energy difference: %.1e, (condition: %.1e)' % (np.absolute((fx - fx0) / self.beads.natoms), self.tolerances["energy"] )
        #print >>f, 'Maximum force component: %.1e, (condition: %.1e)' % (np.amax(np.absolute(self.forces.f+self.im.f)), self.tolerances["force"])
        #print >>f, 'Maximum component step component: %.1e, (condition: %.1e)' % (x, self.tolerances["position"])
        #print >>f, ' '
        # f.close()

        info(' @Exit step: Energy difference: %.1e, (condition: %.1e)' % (np.absolute((fx - fx0) / self.beads.natoms), self.tolerances["energy"]), verbosity.low)
        info(' @Exit step: Maximum force component: %.1e, (condition: %.1e)' % (np.amax(np.absolute(self.forces.f + self.im.f)), self.tolerances["force"]), verbosity.low)
        info(' @Exit step: Maximum component step component: %.1e, (condition: %.1e)' % (x, self.tolerances["position"]), verbosity.low)

        if (np.absolute((fx - fx0) / self.beads.natoms) <= self.tolerances["energy"]) \
                and ((np.amax(np.absolute(self.forces.f + self.im.f)) <= self.tolerances["force"]) or
                     (np.linalg.norm(self.forces.f.flatten() - self.old_f.flatten()) <= 1e-08)) \
                and (x <= self.tolerances["position"]):

            print_instanton_geo(self.prefix + '_FINAL', step, self.im.dbeads.nbeads, self.im.dbeads.natoms, self.im.dbeads.names,
                                self.im.dbeads.q, self.old_u, self.cell, self.energy_shift, self.output_maker)

            if self.hessian_final != 'true':
                info("We are not going to compute the final hessian.", verbosity.low)
                info("Warning, The current hessian is not the real hessian is only an approximation .", verbosity.low)

            else:
                info("We are going to compute the final hessian", verbosity.low)
                get_hessian(self.hessian, self.gm, self.im.dbeads.q, self.output_maker)
                print_instanton_hess(self.prefix + '_FINAL', step, self.hessian, self.output_maker)

            exitt = True  # If we just exit here, the last step (including the last hessian) will not be in the RESTART file

        return exitt
Exemplo n.º 4
0
    def step(self, step=None):
        """ Does one simulation time step."""

        self.qtime = -time.time()
        info("\n Instanton optimization STEP %d" % step, verbosity.low)

        if step == 0:
            info(" @GEOP: Initializing INSTANTON", verbosity.low)

            if self.beads.nbeads == 1:
                info(" @GEOP: Classical TS search", verbosity.low)
                if self.hessian_init == 'true':
                    get_hessian(self.hessian, self.gm, self.beads.q)
            else:
                if ((self.beads.q - self.beads.q[0]) == 0).all(
                ):  # If the coordinates in all the imaginary time slices are the same
                    info(
                        " @GEOP: We stretch the initial geometry with an 'amplitud' of %4.2f"
                        % self.delta, verbosity.low)
                    imvector = get_imvector(self.initial_hessian,
                                            self.beads.m3[0].flatten())
                    for i in range(self.beads.nbeads):
                        self.beads.q[i, :] += self.delta * np.cos(
                            i * np.pi /
                            float(self.beads.nbeads - 1)) * imvector[:]
                    if self.hessian_init != 'true':
                        info(
                            " @GEOP: Hessian_init isn't true but we have stretched the polymer so we are going to compute the initial hessian anyway.",
                            verbosity.low)
                        self.hessian_init = 'true'
                else:
                    info(
                        " @GEOP: Starting from the provided geometry in the extended phase space",
                        verbosity.low)
                    if not (self.initial_hessian is None):
                        raise ValueError(
                            " You have to provided a hessian with size (3xnatoms)^2 but also geometry in the extended phase space (nbeads>1). Please check the inputs\n"
                        )

                if self.hessian_init == 'true':
                    info(" @GEOP: We are computing the initial hessian",
                         verbosity.low)
                    get_hessian(self.hessian, self.gm, self.beads.q)

            # Update positions and forces
            self.old_x[:] = self.beads.q
            self.old_u[:] = self.forces.pots
            self.old_f[:] = self.forces.f

        if type(self.im.f) == type(None):
            self.im(self.beads.q, ret=False)  #Init instanton mapper

        if (self.old_x == np.zeros((self.beads.nbeads, 3 * self.beads.natoms),
                                   float)).all():
            self.old_x[:] = self.beads.q
        if self.exit:
            softexit.trigger(
                "Geometry optimization converged. Exiting simulation")

        if len(self.fixatoms) > 0:
            for dqb in self.old_f:
                dqb[self.fixatoms * 3] = 0.0
                dqb[self.fixatoms * 3 + 1] = 0.0
                dqb[self.fixatoms * 3 + 2] = 0.0

        # Do one step. Update hessian for the new position. Update the position and force inside the mapper.
        Instanton(self.old_x, self.old_f, self.im.f, self.hessian,
                  self.hessian_update, self.hessian_asr, self.im, self.gm,
                  self.big_step, self.opt, self.mode)

        # Update positions and forces
        self.beads.q = self.gm.dbeads.q
        self.forces.transfer_forces(
            self.gm.dforces)  # This forces the update of the forces

        # Print current instanton geometry and hessian
        if (self.save > 0 and np.mod(step, self.save) == 0) or self.exit:
            print_instanton_geo(self.prefix, step, self.im.dbeads.nbeads,
                                self.im.dbeads.natoms, self.im.dbeads.names,
                                self.im.dbeads.q, self.old_u, self.cell,
                                self.energy_shift)
            print_instanton_hess(self.prefix, step, self.hessian)

        # Exit simulation step
        d_x_max = np.amax(np.absolute(np.subtract(self.beads.q, self.old_x)))
        self.exit = self.exitstep(self.forces.pot, self.old_u.sum(), d_x_max,
                                  self.exit, step)

        # Update positions and forces
        self.old_x[:] = self.beads.q
        self.old_u[:] = self.forces.pots
        self.old_f[:] = self.forces.f
Exemplo n.º 5
0
    def step(self, step=None):
        """ Does one simulation time step."""

        self.qtime = -time.time()
        info("\n Instanton optimization STEP %d" % step, verbosity.low)

        if step == 0:
            info(" @GEOP: Initializing instanton", verbosity.low)

            if self.beads.nbeads == 1:
                info(" @GEOP: Classical TS search", verbosity.low)
                if self.hessian_init == 'true':
                    get_hessian(self.hessian, self.gm, self.beads.q, self.output_maker)
            else:
                if ((self.beads.q - self.beads.q[0]) == 0).all():  # If the coordinates in all the imaginary time slices are the same
                    info(" @GEOP: We stretch the initial geometry with an 'amplitud' of %4.2f" % self.delta, verbosity.low)
                    imvector = get_imvector(self.initial_hessian, self.beads.m3[0].flatten())
                    for i in range(self.beads.nbeads):
                        self.beads.q[i, :] += self.delta * np.cos(i * np.pi / float(self.beads.nbeads - 1)) * imvector[:]
                    if self.hessian_init != 'true':
                        info(" @GEOP: Hessian_init isn't true but we have stretched the polymer so we are going to compute the initial hessian anyway.", verbosity.low)
                        self.hessian_init = 'true'
                else:
                    info(" @GEOP: Starting from the provided geometry in the extended phase space", verbosity.low)
                    if not (self.initial_hessian is None):
                        raise ValueError(" You have to provided a hessian with size (3xnatoms)^2 but also geometry in the extended phase space (nbeads>1). Please check the inputs\n")

                if self.hessian_init == 'true':
                    info(" @GEOP: We are computing the initial hessian", verbosity.low)
                    get_hessian(self.hessian, self.gm, self.beads.q, self.output_maker)

            # Update positions and forces
            self.old_x[:] = self.beads.q
            self.old_u[:] = self.forces.pots
            self.old_f[:] = self.forces.f

        if type(self.im.f) == type(None):
            self.im(self.beads.q, ret=False)  # Init instanton mapper

        if (self.old_x == np.zeros((self.beads.nbeads, 3 * self.beads.natoms), float)).all():
            self.old_x[:] = self.beads.q
        if self.exit:
            softexit.trigger("Geometry optimization converged. Exiting simulation")

        if len(self.fixatoms) > 0:
            for dqb in self.old_f:
                dqb[self.fixatoms * 3] = 0.0
                dqb[self.fixatoms * 3 + 1] = 0.0
                dqb[self.fixatoms * 3 + 2] = 0.0

        # Do one step. Update hessian for the new position. Update the position and force inside the mapper.
        Instanton(self.old_x, self.old_f, self.im.f, self.hessian, self.hessian_update, self.hessian_asr, self.im, self.gm, self.big_step, self.opt, self.mode, self.output_maker)

        # Update positions and forces
        self.beads.q = self.gm.dbeads.q
        self.forces.transfer_forces(self.gm.dforces)  # This forces the update of the forces

        # Print current instanton geometry and hessian
        if (self.save > 0 and np.mod(step, self.save) == 0) or self.exit:
            print_instanton_geo(self.prefix, step, self.im.dbeads.nbeads, self.im.dbeads.natoms, self.im.dbeads.names,
                                self.im.dbeads.q, self.old_u, self.cell, self.energy_shift, self.output_maker)
            print_instanton_hess(self.prefix, step, self.hessian, self.output_maker)

        # Exit simulation step
        d_x_max = np.amax(np.absolute(np.subtract(self.beads.q, self.old_x)))
        self.exit = self.exitstep(self.forces.pot, self.old_u.sum(), d_x_max, self.exit, step)

        # Update positions and forces
        self.old_x[:] = self.beads.q
        self.old_u[:] = self.forces.pots
        self.old_f[:] = self.forces.f