def calculate_v1(xms, v0, Fms, symbols, masses, mu, d3, spc_fnc, spc_args, parallel=False): natoms = fncs.howmanyatoms(xms) # Calculation of hessian at close structures xbw_3rd = fncs.ms2cc_x(sd_taylor(xms, d3, v0=-v0), masses, mu) xfw_3rd = fncs.ms2cc_x(sd_taylor(xms, d3, v0=+v0), masses, mu) t3rd_bw = (xbw_3rd, symbols, True, "thirdBw", spc_args) t3rd_fw = (xfw_3rd, symbols, True, "thirdFw", spc_args) # calculation with software if fncs.do_parallel(parallel): import multiprocessing pool = multiprocessing.Pool() out = [ pool.apply_async(spc_fnc, args=args) for args in [t3rd_bw, t3rd_fw] ] #outbw, outfw = Parallel(n_jobs=-1)(delayed(spc_fnc)(*inp) for inp in [t3rd_bw,t3rd_fw]) outbw = out[0].get() outfw = out[1].get() # clean up pool pool.close() pool.join() else: outbw = spc_fnc(*t3rd_bw) outfw = spc_fnc(*t3rd_fw) xcc_bw, atnums, ch, mtp, V0_bw, gcc_bw, Fcc_bw, dummy = outbw xcc_fw, atnums, ch, mtp, V0_fw, gcc_fw, Fcc_fw, dummy = outfw # In mass-scaled Fms_bw = fncs.cc2ms_F(fncs.lowt2matrix(Fcc_bw), masses, mu) Fms_fw = fncs.cc2ms_F(fncs.lowt2matrix(Fcc_fw), masses, mu) # Convert numpy matrices Fms = np.matrix(Fms) Fms_bw = np.matrix(Fms_bw) Fms_fw = np.matrix(Fms_fw) # Matriz of third derivatives m3der = (Fms_fw - Fms_bw) / (2.0 * d3) # Calculation of curvature, i.e. v^(1) (or small c) A = B * c --> c = B^-1 * A LF = np.matrix([v0]).transpose() A = m3der * LF - float(LF.transpose() * m3der * LF) * LF B = 2.0 * float(LF.transpose() * Fms * LF) * np.identity(3 * natoms) - Fms v1 = np.linalg.inv(B) * A # Convert to (normal) array v1 = np.array(v1.transpose().tolist()[0]) return v1
def mep_first(xcc, gcc, Fcc, symbols, masses, var_first, spc_fnc, spc_args, drst={}, parallel=False): #global PARALLEL, delayed, multiprocessing, Parallel #PARALLEL, delayed, multiprocessing, Parallel = fncs.set_parallel(parallel) ds, mu, cubic, idir = var_first # convert cubic variable to d3 (in bohr) d3 = cubic2float(cubic) # mass-scaled xcc = fncs.shift2com(xcc, masses) xms = fncs.cc2ms_x(xcc, masses, mu) gms = fncs.cc2ms_g(gcc, masses, mu) Fms = fncs.cc2ms_F(Fcc, masses, mu) # Data in backup? if TSLABEL in drst.keys(): si, E, xms2, gms, Fms, v0, v1, t = drst[TSLABEL] gms = np.array(gms) Fms = np.array(Fms) v0 = np.array(v0) if v1 is not None: v1 = np.array(v1) same = fncs.same_geom(xms, xms2) if not same: raise Exc.RstDiffTS(Exception) else: # Calculation of v0 freqs, evals, evecs = fncs.calc_ccfreqs(Fcc, masses, xcc) ifreq, Lms = get_imagfreq(freqs, evecs) v0 = fncs.normalize_vec(Lms) v0 = correctdir_v0(xms, v0, idir, masses, mu) # Calculation of v1 if d3 is None: v1 = None else: v1 = calculate_v1(xms, v0, Fms, symbols, masses, mu, d3, spc_fnc, spc_args, parallel) # Final structures if d3 is None: xms_bw = sd_taylor(xms, ds, v0=-v0) xms_fw = sd_taylor(xms, ds, v0=+v0) else: xms_bw = sd_taylor(xms, ds, v0=-v0, v1=-v1) xms_fw = sd_taylor(xms, ds, v0=+v0, v1=+v1) return (xms, gms, Fms), (v0, v1), (xms_bw, xms_fw)
def setup(self, mu=1.0 / AMU, projgrad=False): self._mu = mu # derivated magnitudes (again, in case sth was modified) # for example, when set from gts and masses are added latter self.genderivates() # shift to center of mass and reorientate molecule idata = (self._xcc, self._gcc, self._Fcc, self._masses) self._xcc, self._gcc, self._Fcc = fncs.center_and_orient(*idata) # symmetry self.calc_pgroup(force=False) # Generate mass-scaled arrays self._xms = fncs.cc2ms_x(self._xcc, self._masses, self._mu) self._gms = fncs.cc2ms_g(self._gcc, self._masses, self._mu) self._Fms = fncs.cc2ms_F(self._Fcc, self._masses, self._mu) #-------------# # Atomic case # #-------------# if self._natoms == 1: self._nvdof = 0 self._linear = False #self._xms = list(self._xcc) #self._gms = list(self._gcc) #self._Fms = list(self._Fcc) self._ccfreqs = [] self._ccFevals = [] self._ccFevecs = [] #----------------# # Molecular case # #----------------# else: # Calculate inertia self._itensor = fncs.get_itensor_matrix(self._xcc, self._masses) self._imoms, self._rotTs, self._rtype, self._linear = \ fncs.get_itensor_evals(self._itensor) # Vibrational degrees of freedom if self._linear: self._nvdof = 3 * self._natoms - 5 else: self._nvdof = 3 * self._natoms - 6 # calculate frequencies if self._Fcc is None: return if len(self._Fcc) == 0: return if self._ccfreqs is not None: return v0 = self._gms if projgrad else None data = fncs.calc_ccfreqs(self._Fcc, self._masses, self._xcc, self._mu, v0=v0) self._ccfreqs, self._ccFevals, self._ccFevecs = data # Scale frequencies self._ccfreqs = fncs.scale_freqs(self._ccfreqs, self._fscal)
def steepest(xcc0,s0,symbols,masses,pathdata,spc_fnc,spc_args,drst={},lFms=None,pf="%i"): ''' x0 should not be a saddle point pathdata: tuple made of: * method pm for Page-McIver es for Euler * mu * ds * nsteps * hsteps * epse * epsg pf: point format ''' # expand pathdata method,mu,ds,sfinal,hsteps,epse,epsg = pathdata nsteps = int(round(abs(sfinal/ds))) # Check some staff if lFms is None and method == "pm": raise Exc.SDpmNoHess(Exception) # loop s_i = s0 xcc_i = xcc0 listE = [] listg = [] for step in range(1,nsteps+1): point = pf%step # calculate hessian? if step%hsteps == 0: bhessian = True else : bhessian = False # previously calculated vs single-point calculation if point in drst.keys(): s_ii, E_i, xms_i, gms_i, Fms_i, v0, v1, t_i = drst[point] # in cc gcc_i = fncs.ms2cc_g(gms_i,masses,mu) # compare geometry exception = Exc.RstDiffPoint(Exception) exception._var = (point,s_i) if abs(s_ii-s_i) > EPS_MEPS: raise exception same = fncs.same_geom(fncs.cc2ms_x(xcc_i,masses,mu),xms_i) if not same: raise exception else: spc_data = spc_fnc(xcc_i,symbols,bhessian,point,spc_args) xcc_i, atnums, ch, mtp, E_i, gcc_i, Fcc_i, dummy = spc_data # Data in mass-scaled and correct format Fcc_i = fncs.lowt2matrix(Fcc_i) xms_i = fncs.cc2ms_x(xcc_i,masses,mu) gms_i = fncs.cc2ms_g(gcc_i,masses,mu) Fms_i = fncs.cc2ms_F(Fcc_i,masses,mu) t_i = None # keep data for eps listE.append(E_i) listg.append(fncs.norm(gcc_i)) # Last Fms if Fms_i not in [[],None]: lFms = Fms_i # Calculate new geometry (step+1) if method == "es": xms_j, t_i = sd_taylor(xms_i,ds,gms=gms_i), None # to check format elif method == "pm": xms_j, t_i = pm_nextxms(xms_i,ds,gms=gms_i,Fms=lFms,t0=t_i) # check real ds value diff_ds2 = sum([(ii-jj)**2 for (ii,jj) in zip(xms_j,xms_i)]) - ds**2 if diff_ds2 > EPS_FLOAT: raise Exc.SDdiffds(Exception) # Yield updated data for step yield (point,s_i), E_i, xms_i, gms_i, Fms_i, t_i # update xcc_i = fncs.ms2cc_x(xms_j,masses,mu) if s_i >= 0.0: s_i += ds else : s_i -= ds # Check eps if len(listE) > 2 and step > 2*hsteps: diffE = abs(listE[-1]-listE[-2]) #diffg = abs(listg[-1]-listg[-2]) crit1 = diffE < epse crit2 = listg[-1] < epsg if crit1 and crit2: break