Esempio n. 1
0
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)
Esempio n. 2
0
    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)
Esempio n. 3
0
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