Esempio 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)
Esempio n. 2
0
    def step(self, step=None):
        """ Does one simulation time step."""

        activearrays = self.pre_step(step)

        # First construct complete hessian from reduced
        h0 = red2comp(activearrays["hessian"], self.im.dbeads.nbeads, self.im.dbeads.natoms, self.im.coef)

        # Add spring terms to the physical hessian
        h1 = np.add(self.im.h, h0)

        # Get eigenvalues and eigenvector.
        d, w = clean_hessian(h1, self.im.dbeads.q, self.im.dbeads.natoms,
                             self.im.dbeads.nbeads, self.im.dbeads.m, self.im.dbeads.m3, self.options["hessian_asr"])

        # d,w =np.linalg.eigh(h1) #Cartesian
        info('\n@Nichols: 1st freq {} cm^-1'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[0]) * np.sqrt(np.absolute(d[0])))), verbosity.medium)
        info('@Nichols: 2nd freq {} cm^-1'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[1]) * np.sqrt(np.absolute(d[1])))), verbosity.medium)
        info('@Nichols: 3rd freq {} cm^-1'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[2]) * np.sqrt(np.absolute(d[2])))), verbosity.medium)
        #info('@Nichols: 4th freq {} cm^-1'.format(units.unit_to_user('frequency','inversecm',np.sign(d[3])*np.sqrt(np.absolute(d[3])))),verbosity.medium)
        #info('@Nichols: 8th freq {} cm^-1\n'.format(units.unit_to_user('frequency','inversecm',np.sign(d[7])*np.sqrt(np.absolute(d[7])))),verbosity.medium)

        # Find new movement direction
        if self.options["mode"] == 'rate':
            f = activearrays["old_f"] * (self.im.coef[1:] + self.im.coef[:-1]) / 2
            d_x = nichols(f, self.im.f, d, w, self.im.dbeads.m3, activearrays["big_step"])
        elif self.options["mode"] == 'splitting':
            d_x = nichols(activearrays["old_f"], self.im.f, d, w, self.im.dbeads.m3, activearrays["big_step"], mode=0)

        # Rescale step if necessary
        if np.amax(np.absolute(d_x)) > activearrays["big_step"]:
            info("Step norm, scaled down to {}".format(activearrays["big_step"]), verbosity.low)
            d_x *= activearrays["big_step"] / np.amax(np.absolute(d_x))

        # Get the new full-position
        d_x_full = self.fix.get_full_vector(d_x, t=1)
        new_x = self.optarrays["old_x"].copy() + d_x_full

        self.post_step(step, new_x, d_x, activearrays)
Esempio n. 3
0
    pots = simulation.syslist[0].motion.optarrays["old_u"]
    grads = -simulation.syslist[0].motion.optarrays["old_f"]
    V0 = simulation.syslist[0].motion.optarrays["energy_shift"]

    if V00 != 0.0:
        print("Overwriting energy shift with the provided values")
        V0 = V00 * eV2au

    if np.absolute(temp - temp2) / K2au > 2:
        print(
            "\n Mismatch between provided temperature and temperature in the calculation"
        )
        sys.exit()

    if mode == "rate":
        h0 = red2comp(hessian, nbeads, natoms)
        pos, nbeads, hessian2 = get_double(beads.q, nbeads, natoms, h0)
        hessian = hessian2
        m3 = np.concatenate((beads.m3, beads.m3), axis=0)
        omega2 = (temp * nbeads * kb / hbar) ** 2
        if not quiet:
            spring = SpringMapper.spring_hessian(
                natoms, nbeads, beads.m3[0], omega2, mode="full"
            )
            h = np.add(hessian, spring)
    elif mode == "splitting":
        if input_freq is None:
            print(
                'Please provide a name of the file containing the list of the frequencies for the minimum using "-freq" flag'
            )
            print(" You can generate that file using this script in the case reactant.")
Esempio n. 4
0
    def step(self, step=None):
        """ Does one simulation time step."""

        activearrays = self.pre_step(step)

        fff = activearrays["old_f"] * (self.im.coef[1:] + self.im.coef[:-1]) / 2
        f = (fff + self.im.f).reshape(self.im.dbeads.natoms * 3 * self.im.dbeads.nbeads, 1)

        banded = False
        banded = True
        if banded:
            # BANDED Version
            # MASS-scaled
            dyn_mat = get_dynmat(activearrays["hessian"], self.im.dbeads.m3, self.im.dbeads.nbeads)
            h_up_band = banded_hessian(dyn_mat, self.im, masses=False, shift=0.000000001)  # create upper band matrix
            f = np.multiply(f, self.im.dbeads.m3.reshape(f.shape)**-0.5)
            # CARTESIAN
            # h_up_band = banded_hessian(activearrays["hessian"], self.im,masses=True)  # create upper band matrix

            d = diag_banded(h_up_band)
        else:
            # FULL dimensions version
            h_0 = red2comp(activearrays["hessian"], self.im.dbeads.nbeads, self.im.dbeads.natoms, self.im.coef)
            h_test = np.add(self.im.h, h_0)  # add spring terms to the physical hessian
            d, w = clean_hessian(h_test, self.im.dbeads.q, self.im.dbeads.natoms,
                                 self.im.dbeads.nbeads, self.im.dbeads.m, self.im.dbeads.m3, None)
            # CARTESIAN
            # d,w =np.linalg.eigh(h_test) #Cartesian
        info('\n@Lanczos: 1st freq {} cm^-1'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[0]) * np.sqrt(np.absolute(d[0])))), verbosity.medium)
        info('@Lanczos: 2nd freq {} cm^-1'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[1]) * np.sqrt(np.absolute(d[1])))), verbosity.medium)
        info('@Lanczos: 3rd freq {} cm^-1\n'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[2]) * np.sqrt(np.absolute(d[2])))), verbosity.medium)

        if d[0] > 0:
            if d[1] / 2 > d[0]:
                alpha = 1
                lamb = (2 * d[0] + d[1]) / 4
            else:
                alpha = (d[1] - d[0]) / d[1]
                lamb = (3 * d[0] + d[1]) / 4  # midpoint between b[0] and b[1]*(1-alpha/2)
        elif d[1] < 0:  # Jeremy Richardson
            if (d[1] >= d[0] / 2):
                alpha = 1
                lamb = (d[0] + 2 * d[1]) / 4
            else:
                alpha = (d[0] - d[1]) / d[1]
                lamb = (d[0] + 3 * d[1]) / 4
        # elif d[1] < 0:  #Litman for Second Order Saddle point
        #    alpha = 1
        #    lamb = (d[1] + d[2]) / 4
        #    print 'WARNING: We are not using the standard Nichols'
        #    print 'd_x', d_x[0],d_x[1]

        else:  # Only d[0] <0
            alpha = 1
            lamb = (d[0] + d[1]) / 4

        if banded:
            h_up_band[-1, :] += - np.ones(h_up_band.shape[1]) * lamb
            d_x = invmul_banded(h_up_band, f)
        else:
            h_test = alpha * (h_test - np.eye(h_test.shape[0]) * lamb)
            d_x = np.linalg.solve(h_test, f)

        d_x.shape = self.im.dbeads.q.shape

        # MASS-scaled
        d_x = np.multiply(d_x, self.im.dbeads.m3**-0.5)

        # Rescale step if necessary
        if np.amax(np.absolute(d_x)) > activearrays["big_step"]:
            info("Step norm, scaled down to {}".format(activearrays["big_step"]), verbosity.low)
            d_x *= activearrays["big_step"] / np.amax(np.absolute(d_x))

        # Get the new full-position
        d_x_full = self.fix.get_full_vector(d_x, t=1)
        new_x = self.optarrays["old_x"].copy() + d_x_full

        self.post_step(step, new_x, d_x, activearrays)
Esempio n. 5
0
    grads = -simulation.syslist[0].motion.old_f
    V0 = simulation.syslist[0].motion.energy_shift

    if V00 != 0.0:
        print 'Overwriting energy shift with the provided values'
        V0 = V00 * eV2au

    if np.absolute(temp - temp2) / K2au > 2:
        print ' '
        print 'Mismatch between provided temperature and temperature in the calculation'
        sys.exit()
    print 'The instanton mode is %s' % mode
    print 'The temperature is %f K' % (temp / K2au)

    if mode == 'rate':
        h0 = red2comp(hessian, nbeads, natoms)
        pos, nbeads, hessian2 = get_double(beads.q, nbeads, natoms, h0)
        hessian = hessian2
        m3 = np.concatenate((beads.m3, beads.m3), axis=0)
        omega2 = (temp * nbeads * kb / hbar) ** 2
        if not quiet:
            spring = SpringMapper.spring_hessian(natoms, nbeads, beads.m3[0], omega2, mode='full')
            h = np.add(hessian, spring)
        print 'The full ring polymer is made of %i' % (nbeads)
        print 'We used %i beads in the calculation.' % (nbeads / 2)
    elif mode == 'splitting':
        if input_freq == None:
            print 'Please provide a name of the file containing the list of the frequencies for the minimum using "-freq" flag'
            print '(You can generate that file using this script in the case reactant.)'
            sys.exit()