Exemple #1
0
def numv1_calcA(all_points, all_svals, grads, hess_idxsBW, hess_idxsFW):
    '''
    svals: the list of s values
    grads: the list of gradients
    hess_idxs: a list of indices indicating where v^(1)
               has to be calculated
               this is given in two list, one for the bw and
               another for the fw part of the MEP
               why? although each coordinate of the gradient is continuous along the mep,
               this behavior is not found for the v^(0) vector.
    '''
    dv1 = {}
    for indices in [hess_idxsBW, hess_idxsFW]:
        for idx in indices:
            # label for this point
            label = all_points[idx]

            # Choose the points
            if idx == indices[0]: idx_a, idx_b, idx_c = idx, idx + 1, idx + 2
            elif idx == indices[-1]:
                idx_a, idx_b, idx_c = idx - 2, idx - 1, idx
            else:
                idx_a, idx_b, idx_c = idx - 1, idx, idx + 1

            # s for the three points of mep
            si = all_svals[idx]
            sa = all_svals[idx_a]
            sb = all_svals[idx_b]
            sc = all_svals[idx_c]

            # Get v^(0) at each point
            v0_a = -fncs.normalize_vec(grads[idx_a])
            v0_b = -fncs.normalize_vec(grads[idx_b])
            v0_c = -fncs.normalize_vec(grads[idx_c])

            # Parabolic function for each coordinate
            ncoords = len(v0_a)
            v1 = []
            for coord in range(ncoords):
                x1, x2, x3 = sa, sb, sc
                y1, y2, y3 = v0_a[coord], v0_b[coord], v0_c[coord]
                # Get a in a*x^2 + b*x + c
                num_a = (y1 - y2) * (x1 - x3) - (y1 - y3) * (x1 - x2)
                den_a = (x1**2 - x2**2) * (x1 - x3) - (x1**2 - x3**2) * (x1 -
                                                                         x2)
                a = num_a / den_a
                # Get b in b*x^2 + b*x + c
                b = ((y1 - y2) - a * (x1**2 - x2**2)) / (x1 - x2)
                # Get c in b*x^2 + b*x + c
                c = y1 - a * x1**2 - b * x1
                # Get derivative at x=s (y' = 2*a*x+b)
                v1_coord = 2 * a * si + b
                v1.append(v1_coord)
            dv1[label] = np.array(v1)
    return dv1
Exemple #2
0
def numv1_calcB(points, svals, grads, hess_idxs):
    '''
    average of linear interpolation
    it is equivalent to numv1_calcA, but faster
    _cu for current point
    _m1 for previous point to current
    _m2 for previous point to _m1
    _p1 for next point with regard to current
    _p2 for next point with regard to _p1
    et cetera
    '''
    dv1 = {}
    saddle_idx = None

    for idx, label in enumerate(points):
        if idx not in hess_idxs: continue
        # Current point
        s_cu = svals[idx]
        g_cu = np.array(grads[idx])
        # Skip if saddle point
        if s_cu == 0.0: continue
        # v0 vector
        v0_cu = -fncs.normalize_vec(g_cu)
        # Previous point
        if idx != 0:
            s_m1 = svals[idx - 1]
            g_m1 = np.array(grads[idx - 1])
            v0_m1 = -fncs.normalize_vec(g_m1)
            # Get left derivative
            v1_left = (v0_cu - v0_m1) / (s_cu - s_m1)
        else:
            v1_left = None
        # Next point
        if idx != len(points) - 1:
            s_p1 = svals[idx + 1]
            g_p1 = np.array(grads[idx + 1])
            v0_p1 = -fncs.normalize_vec(g_p1)
            # Get right derivative
            v1_right = (v0_p1 - v0_cu) / (s_p1 - s_cu)
        else:
            v1_right = None
        # average
        if v1_left is None: v1 = v1_right
        elif v1_right is None: v1 = v1_left
        else: v1 = (v1_right + v1_left) / 2.0
        # save
        dv1[label] = v1
    return dv1
Exemple #3
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)
Exemple #4
0
def puckering_normal(list_Rj):
    ''' JACS 1975, 97:6, 1354-1358; eq (10) '''
    N   = len(list_Rj)
    Rp  = np.array([0.0,0.0,0.0])
    Rpp = np.array([0.0,0.0,0.0])
    for j in range(N):
        Rj   = list_Rj[j]
        sin  = np.sin(2*np.pi*j/N)
        cos  = np.cos(2*np.pi*j/N)
        Rp  += sin * Rj
        Rpp += cos * Rj
    normal = np.cross(Rp,Rpp)
    return fncs.normalize_vec(normal)