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)
asr = 'none' else: print 'We can not recognize the mode. STOP HERE' sys.exit() #----------------------------------------------------------START---------------------------------------------- beta = 1.0 / (kb * temp) betaP = 1.0 / (kb * (nbeads) * temp) print 'We have %i atoms.' % natoms print 'We are using asr = %s' % asr print '' if not quiet: print 'Diagonalization....' d, w, detI = clean_hessian(h, pos, natoms, nbeads, m, m3, asr, mofi=True) print "Final lowest 15 frequencies (cm^-1)" print np.sign(d[0:15]) * np.absolute( d[0:15])**0.5 / cm2au # convert to cm^-1 if case == 'reactant': Qtras = ((np.sum(m)) / (2 * np.pi * beta * hbar**2))**1.5 if asr == 'poly': Qrot = (8 * np.pi * detI / ((hbar)**6 * (beta)**3))**0.5 else: Qrot = 1.0 outfile = open('freq.dat', 'w') if asr == 'poly': nzeros = 6
asr = 'none' else: print 'We can not recognize the mode. STOP HERE' sys.exit() # ----------------------------------------------------------START---------------------------------------------- beta = 1.0 / (kb * temp) betaP = 1.0 / (kb * (nbeads) * temp) print 'We have %i atoms.' % natoms print 'We are using asr = %s' % asr print '' if not quiet: print 'Diagonalization....' d, w, detI = clean_hessian(h, pos, natoms, nbeads, m, m3, asr, mofi=True) print "Final lowest 15 frequencies (cm^-1)" print np.sign(d[0:15]) * np.absolute(d[0:15]) ** 0.5 / cm2au # convert to cm^-1 if case == 'reactant': Qtras = ((np.sum(m)) / (2 * np.pi * beta * hbar**2))**1.5 if asr == 'poly': Qrot = (8 * np.pi * detI / ((hbar)**6 * (beta)**3))**0.5 else: Qrot = 1.0 outfile = open('freq.dat', 'w') if asr == 'poly': nzeros = 6 elif asr == 'crystal':