예제 #1
0
def get_surface(lepsgui):
    """Get Vmat (potential) for a given set of parameters"""
    lepsgui.get_params()

    #Check if params have changed. If not, no need to recalculate
    if lepsgui.old_params == lepsgui.params and not lepsgui._firstrun:
        return

    resl = 0.02  #Resolution
    lepsgui._firstrun = False

    #Get grid
    lepsgui.Grid_X = np.arange(lepsgui.params.mina, lepsgui.params.maxa, resl)
    lepsgui.Grid_Y = np.arange(lepsgui.params.minb, lepsgui.params.maxb, resl)
    lepsgui.Vmat = np.zeros((len(lepsgui.Grid_Y), len(lepsgui.Grid_X)))

    #Calculate potential for each gridpoint
    for drabcount, drab in enumerate(lepsgui.Grid_X):
        lepsgui.Current_Separations[0] = drab
        for drbccount, drbc in enumerate(lepsgui.Grid_Y):
            lepsgui.Current_Separations[1] = drbc

            V = lepspoint(np.deg2rad(lepsgui.theta),
                          lepsgui.params.Dissociation_energies,
                          lepsgui.params.Reqs,
                          lepsgui.params.Morse_Parameters,
                          lepsgui.params.surface_param,
                          lepsgui.Current_Separations,
                          lepsgui.Current_First_derivative,
                          lepsgui.Current_Hessian,
                          derivative=0)
            lepsgui.Vmat[drbccount, drabcount] = V

    lepsgui.old_params = lepsgui.params
예제 #2
0
    def get_surface(self):
        """Get Vmat (potential) for a given set of parameters"""
        self.get_params()

        #Check if params have changed. If not, no need to recalculate
        new_params = [self.a, self.b, self.c, self.theta]
        if self.old_params == new_params and not self._firstrun:
            return

        resl = 0.02  #Resolution
        grad = 0  #Gradient calc type (0 = energy)
        self._firstrun = False

        #Get grid
        self.x = np.arange(self.mina, self.maxa, resl)
        self.y = np.arange(self.minb, self.maxb, resl)
        self.Vmat = np.zeros((len(self.y), len(self.x)))

        #Calculate potential for each gridpoint
        for drabcount, drab in enumerate(self.x):
            for drbccount, drbc in enumerate(self.y):

                V = lepspoint(drab, drbc, np.deg2rad(self.theta), self.Drab,
                              self.Drbc, self.Drac, self.Brab, self.Brbc,
                              self.Brac, self.lrab, self.lrbc, self.lrac,
                              self.H, grad)
                self.Vmat[drbccount, drabcount] = V

        self.old_params = new_params
예제 #3
0
def get_first(lepsgui):
    """1 step of trajectory to get geometry properties"""
    lepsgui._read_entries()
    lepsgui.get_params()

    lepsgui.current_potential_energy = lepspoint(
        np.deg2rad(lepsgui.theta), lepsgui.params.Dissociation_energies,
        lepsgui.params.Reqs, lepsgui.params.Morse_Parameters,
        lepsgui.params.surface_param, lepsgui.Current_Separations,
        lepsgui.Current_First_derivative, lepsgui.Current_Hessian, 2)

    lepsgui.theta, lepsgui.current_kinetic_energy = lepnorm(
        np.deg2rad(lepsgui.theta), lepsgui.Current_Separations,
        lepsgui.Current_First_derivative, lepsgui.Current_Hessian,
        lepsgui.Current_Velocities, lepsgui.Current_Accelerations,
        lepsgui.params.Masses, lepsgui.params.Reduced_masses, lepsgui.dt,
        False)
예제 #4
0
 def get_first(self):
     """1 step of trajectory to get geometry properties"""
     self._read_entries()
     self.get_params()
     dt   = self.dt
     
     ma   = self.ma
     mb   = self.mb
     mc   = self.mc
     
     mab  = self.mab
     mbc  = self.mbc
     
     Drab = self.Drab
     Drbc = self.Drbc
     Drac = self.Drac
     
     lrab = self.lrab
     lrbc = self.lrbc
     lrac = self.lrac
     
     Brab = self.Brab
     Brbc = self.Brbc
     Brac = self.Brac
     
     xrabi = self.xrabi
     xrbci = self.xrbci
     prabi = self.prabi
     prbci = self.prbci
     
     thetai = np.deg2rad(self.theta)
     
     vrabi = prabi / mab
     vrbci = prbci / mbc
     vraci = 0
     
     grad = 2
     ti = 0
     
     Vrinti,Frabi,Frbci,Fraci,hr1r1i,hr1r2i,hr1r3i,hr2r2i,hr2r3i,hr3r3i = lepspoint(xrabi,xrbci,thetai,Drab,Drbc,Drac,Brab,Brbc,Brac,lrab,lrbc,lrac,self.H,grad)
     xrabf,xrbcf,xracf,thetaf,vrabf,vrbcf,vracf,tf,arabi,arbci,araci,Ktoti = lepnorm(xrabi,xrbci,thetai,Frabi,Frbci,Fraci,vrabi,vrbci,vraci,hr1r1i,hr1r2i,hr1r3i,hr2r2i,hr2r3i,hr3r3i,ma,mb,mc,ti,dt,False)
     
     return Vrinti,Frabi,Frbci,Fraci,hr1r1i,hr1r2i,hr1r3i,hr2r2i,hr2r3i,hr3r3i,xrabf,xrbcf,xracf,thetaf,vrabf,vrbcf,vracf,tf,arabi,arbci,araci,Ktoti
예제 #5
0
def get_trajectory(lepsgui):
    """Get dynamics, MEP or optimisation"""

    dt = lepsgui.dt  #Time step
    lepsgui.current_time = 0

    thetai = np.deg2rad(lepsgui.theta)  #Collision Angle
    grad = 2  #Calculating gradients and Hessian

    lepsgui.get_arrays()
    lepsgui.Animation_Positions = []
    lepsgui.append_animation_position()

    #Initial Velocity
    lepsgui.Current_Velocities = lepsgui.Current_Momenta / lepsgui.params.Reduced_masses
    lepsgui.Trajectory_Velocities = []

    #Initialise outputs
    lepsgui.Trajectory_times = []
    lepsgui.Trajectory_Separations = []
    lepsgui.Trajectory_Velocities = []
    lepsgui.Trajectory_Momenta = []
    lepsgui.Trajectory_Accelerations = []
    lepsgui.Trajectory_First_derivatives = []
    lepsgui.Trajectory_Hessians = []
    lepsgui.Potential_Energies = []
    lepsgui.Kinetic_Energies = []
    lepsgui.Potential_Energies = []
    lepsgui.Total_Energies = []

    #Initial conditions
    lepsgui.current_potential_energy = lepspoint(
        thetai, lepsgui.params.Dissociation_energies, lepsgui.params.Reqs,
        lepsgui.params.Morse_Parameters, lepsgui.params.surface_param,
        lepsgui.Current_Separations, lepsgui.Current_First_derivative,
        lepsgui.Current_Hessian, grad)

    lepsgui.add_trajectory_step()

    #Flag to stop appending to output in case of a crash
    terminate = False

    for itcounter in range(lepsgui.steps):
        if lepsgui.calc_type != "Dynamics":
            lepsgui.Current_Velocities = np.zeros((3))

        #Get current potential, forces, and Hessian
        lepsgui.current_potential_energy = lepspoint(
            thetai, lepsgui.params.Dissociation_energies, lepsgui.params.Reqs,
            lepsgui.params.Morse_Parameters, lepsgui.params.surface_param,
            lepsgui.Current_Separations, lepsgui.Current_First_derivative,
            lepsgui.Current_Hessian, grad)

        if lepsgui.calc_type in ["Opt Min",
                                 "Opt TS"]:  #Optimisation calculations

            #Diagonalise Hessian
            eigenvalues, eigenvectors = np.linalg.eig(lepsgui.Current_Hessian)

            #Eigenvalue test
            neg_eig_i = [i for i, eig in enumerate(eigenvalues) if eig < -0.01]
            if len(neg_eig_i) == 0 and lepsgui.calc_type == "Opt TS":
                msgbox.showinfo("Eigenvalues Info",
                                "No negative eigenvalues at this geometry")
                terminate = True
            elif len(neg_eig_i) == 1 and lepsgui.calc_type == "Opt Min":
                msgbox.showerror(
                    "Eigenvalues Error",
                    "Too many negative eigenvalues at this geometry")
                terminate = True
            elif len(neg_eig_i) > 1:
                msgbox.showerror(
                    "Eigenvalues Error",
                    "Too many negative eigenvalues at this geometry")
                terminate = True

            #Optimiser
            Displacements = np.array([0., 0., 0.])
            for mode in range(len(eigenvalues)):
                e_val = eigenvalues[mode]
                e_vec = eigenvectors[mode]

                disp = np.dot(
                    np.dot((e_vec.T), lepsgui.Current_First_derivative),
                    e_vec) / e_val
                Displacements += disp

            lepsgui.Current_Separations += Displacements
            #xrabf = xrabi + disps[0]
            #xrbcf = xrbci + disps[1]
            #xracf = ((xrabf ** 2) + (xrbcf ** 2) - 2 * xrabf * xrbcf * np.cos(thetai)) ** 0.5

        else:  #Dynamics/MEP
            try:
                lepsgui.theta, lepsgui.current_kinetic_energy = lepnorm(
                    lepsgui.theta, lepsgui.Current_Separations,
                    lepsgui.Current_First_derivative, lepsgui.Current_Hessian,
                    lepsgui.Current_Velocities, lepsgui.Current_Accelerations,
                    lepsgui.params.Masses, lepsgui.params.Reduced_masses,
                    lepsgui.dt, False)
                lepsgui.current_time += lepsgui.dt

            except LinAlgError:
                msgbox.showerror(
                    "Surface Error",
                    "Energy could not be evaulated at step {}. Steps truncated"
                    .format(itcounter + 1))
                terminate = True

        if lepsgui.Current_Separations[
                0] > lepsgui.lim or lepsgui.Current_Separations[
                    1] > lepsgui.lim:  #Stop calc if distance lim is exceeded
            msgbox.showerror(
                "Surface Error",
                "Surface Limits exceeded at step {}. Steps truncated".format(
                    itcounter + 1))
            terminate = True

        if lepsgui.calc_type != "Dynamics":
            lepsgui.Current_Velocities = np.zeros((3))

        if itcounter != lepsgui.steps - 1 and not terminate:

            #As above
            lepsgui.append_animation_position()

            ### Maybe not necessary
            #Get A-C Velocity
            r0 = np.linalg.norm(lepsgui.Trajectory_Separations[-1][2] -
                                lepsgui.Trajectory_Separations[-1][0])
            r1 = np.linalg.norm(lepsgui.Current_Separations[2] -
                                lepsgui.Current_Separations[0])
            vrac = (r1 - r0) / dt

            lepsgui.add_trajectory_step()

        if terminate:
            break
예제 #6
0
    def get_trajectory(self):
        """Get dynamics, MEP or optimisation"""

        itlimit = self.steps  #Max number of steps
        dt = self.dt  #Time step
        ti = 0  #Initial time variable
        tf = 0  #Final time variable

        ma = self.ma  #Mass of A
        mb = self.mb  #Mass of B
        mc = self.mc  #Mass of C

        mab = self.mab  #Reduced mass of AB
        mbc = self.mbc  #Reduced mass of BC

        Drab = self.Drab
        Drbc = self.Drbc
        Drac = self.Drac

        lrab = self.lrab
        lrbc = self.lrbc
        lrac = self.lrac

        Brab = self.Brab
        Brbc = self.Brbc
        Brac = self.Brac

        thetai = np.deg2rad(self.theta)  #Collision Angle
        grad = 2  #Calculating gradients and Hessian

        xrabi = self.xrabi  #Initial AB separation
        xrbci = self.xrbci  #Initial BC separation
        xraci = (
            (xrabi**2) + (xrbci**2) -
            2 * xrabi * xrbci * np.cos(thetai))**0.5  #Initial AC separation
        prabi = self.prabi  #Initial AB momentum
        prbci = self.prbci  #Initial BC momentum

        vrabi = prabi / mab  #Initial AB Velocity
        vrbci = prbci / mbc  #Initial BC Velocity

        #Positions of A, B and C relative to B
        a = np.array([-xrabi, 0.])
        b = np.array([0., 0.])
        c = np.array([-np.cos(thetai) * xrbci, np.sin(thetai) * xrbci])

        #Get centre of mass
        com = (a * ma + b * mb + c * mc) / (ma + mb + mc)
        com = np.real(com)

        #Translate to centre of mass (for animation)
        a -= com
        b -= com
        c -= com

        self.ra = [a]
        self.rb = [b]
        self.rc = [c]

        #Initial AC Velocity
        va = (a - self.ra[-1]) / dt
        vc = (c - self.rc[-1]) / dt
        vraci = np.linalg.norm(va + vc)

        #Initialise outputs
        self.xrab = [xrabi]
        self.xrbc = [xrbci]
        self.xrac = [xraci]
        self.vrab = [vrabi]
        self.vrbc = [vrbci]
        self.vrac = [vraci]
        self.t = [ti]

        self.Vrint = Vrint = []
        self.Ktot = Ktot = []

        self.Frab = Frab = []
        self.Frbc = Frbc = []
        self.Frac = Frac = []
        self.arab = arab = []
        self.arbc = arbc = []
        self.arac = arac = []
        self.etot = etot = []

        self.hr1r1 = hr1r1 = []
        self.hr1r2 = hr1r2 = []
        self.hr1r3 = hr1r3 = []
        self.hr2r2 = hr2r2 = []
        self.hr2r3 = hr2r3 = []
        self.hr3r3 = hr3r3 = []

        #Flag to stop appending to output in case of a crash
        terminate = False

        for itcounter in range(itlimit):
            if self.calc_type != "Dynamics":
                vrabi = 0
                vrbci = 0
                vraci = 0

            #Get current potential, forces, and Hessian
            Vrinti, Frabi, Frbci, Fraci, hr1r1i, hr1r2i, hr1r3i, hr2r2i, hr2r3i, hr3r3i = lepspoint(
                xrabi, xrbci, thetai, Drab, Drbc, Drac, Brab, Brbc, Brac, lrab,
                lrbc, lrac, self.H, grad)
            Vrint.append(Vrinti)
            Frab.append(Frabi)
            Frbc.append(Frbci)
            Frac.append(Fraci)
            hr1r1.append(hr1r1i)
            hr1r2.append(hr1r2i)
            hr1r3.append(hr1r3i)
            hr2r2.append(hr2r2i)
            hr2r3.append(hr2r3i)
            hr3r3.append(hr3r3i)

            if self.calc_type in ["Opt Min",
                                  "Opt TS"]:  #Optimisation calculations

                #Diagonalise Hessian
                hessian = np.array([[hr1r1i, hr1r2i, hr1r3i],
                                    [hr1r2i, hr2r2i, hr2r3i],
                                    [hr1r3i, hr2r3i, hr3r3i]])
                eigenvalues, eigenvectors = np.linalg.eig(hessian)

                #Get forces for opt calculation
                forces = np.array([Frabi, Frbci, Fraci])

                #Eigenvalue test
                neg_eig_i = [
                    i for i, eig in enumerate(eigenvalues) if eig < -0.01
                ]
                if len(neg_eig_i) == 0 and self.calc_type == "Opt TS":
                    msgbox.showinfo(
                        "Eigenvalues Info",
                        "No negative eigenvalues at this geometry")
                    terminate = True
                elif len(neg_eig_i) == 1 and self.calc_type == "Opt Min":
                    msgbox.showerror(
                        "Eigenvalues Error",
                        "Too many negative eigenvalues at this geometry")
                    terminate = True
                elif len(neg_eig_i) > 1:
                    msgbox.showerror(
                        "Eigenvalues Error",
                        "Too many negative eigenvalues at this geometry")
                    terminate = True

                #Optimiser
                disps = np.array([0., 0., 0.])
                for mode in range(len(eigenvalues)):
                    e_val = eigenvalues[mode]
                    e_vec = eigenvectors[mode]

                    disp = np.dot(np.dot((e_vec.T), forces), e_vec) / e_val
                    disps += disp

                xrabf = xrabi + disps[0]
                xrbcf = xrbci + disps[1]
                xracf = ((xrabf**2) + (xrbcf**2) -
                         2 * xrabf * xrbcf * np.cos(thetai))**0.5

                arabi = 0
                arbci = 0
                araci = 0
                thetaf = thetai
                vrabf = 0
                vrbcf = 0
                vracf = 0
                Ktoti = 0
                tf += dt

            else:  #Dynamics/MEP
                try:
                    xrabf, xrbcf, xracf, thetaf, vrabf, vrbcf, vracf, tf, arabi, arbci, araci, Ktoti = lepnorm(
                        xrabi, xrbci, thetai, Frabi, Frbci, Fraci, vrabi,
                        vrbci, vraci, hr1r1i, hr1r2i, hr1r3i, hr2r2i, hr2r3i,
                        hr3r3i, ma, mb, mc, ti, dt, self.calc_type == "MEP")
                except LinAlgError:
                    msgbox.showerror(
                        "Surface Error",
                        "Energy could not be evaulated at step {}. Steps truncated"
                        .format(itcounter + 1))
                    terminate = True

            if xrabf > self.lim or xrbcf > self.lim:  #Stop calc if distance lim is exceeded
                msgbox.showerror(
                    "Surface Error",
                    "Surface Limits exceeded at step {}. Steps truncated".
                    format(itcounter + 1))
                terminate = True

            arab.append(arabi)
            arbc.append(arbci)
            arac.append(araci)
            Ktot.append(Ktoti)

            #Total energy
            etot.append(Vrint[itcounter] + Ktot[itcounter])

            if itcounter != itlimit - 1 and not terminate:

                #As above
                a = np.array([-xrabf, 0.])
                b = np.array([0., 0.])
                c = np.array([-np.cos(thetaf) * xrbcf, np.sin(thetaf) * xrbcf])
                com = (a * ma + b * mb + c * mc) / (ma + mb + mc)

                com = np.real(com)

                a -= com
                b -= com
                c -= com

                #Get A-C Velocity
                r0 = np.linalg.norm(self.rc[-1] - self.ra[-1])
                r1 = np.linalg.norm(c - a)
                vrac = (r1 - r0) / dt

                self.ra.append(a)  #A  Pos
                self.rb.append(b)  #B  Pos
                self.rc.append(c)  #C  Pos
                self.xrab.append(xrabf)  #A-B Distance
                self.xrbc.append(xrbcf)  #B-C Distance
                self.xrac.append(xracf)  #A-C Distance
                if self.calc_type == "Dynamics":
                    self.vrab.append(vrabf)  #A-B Velocity
                    self.vrbc.append(vrbcf)  #B-C Velocity
                    self.vrac.append(vrac)  #A-C Velocity
                else:
                    self.vrab.append(0.)  #A-B Velocity
                    self.vrbc.append(0.)  #B-C Velocity
                    self.vrac.append(0.)  #A-C Velocity
                self.t.append(tf)  #Time

            xrabi = xrabf
            xrbci = xrbcf
            xraci = xracf
            vrabi = vrabf
            vrbci = vrbcf
            vraci = vracf
            ti = tf

            if terminate:
                break