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)
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)
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.")
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)
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()