Пример #1
0
def force_morse(particle1, particle2, re, de, a):
    """
        Gives the Morse force between particles interacting via the Morse potential
        
        :param re: equilibrium bond distance
        :param de: parameter controlling depth of the potential minimum
        :param a: parameter controlling curvature of the potential minimum (small a -> wide well)
        """
    r12 = np.linalg.norm(Particle3D.separation(particle1, particle2))
    exp = math.exp(-a * (r12 - re))
    unit_r = np.true_divide(Particle3D.separation(particle1, particle2), r12)
    force = 2 * a * de * (1 - exp) * exp * unit_r

    return force
Пример #2
0
def check_observables(particle_list, max_arr, min_arr, wrt_arr, time,
                      orbit_complete_flags, period_arr):
    """
    Computes the observables for the planets
    Inputs:
    list particle_list: list of particles
    array max_arr: array of current maximum orbit disances (float)
    array min_arr: array of current maximum orbit disances (float)
    wrt_arr: array of integers corresponding to the index of the particle that the particle of the index of the element is orbiting
    time: current time in simulation (float)
    orbit_complete_flags: boolean array that is true when the particle with that index has traversed 2pi radians
    period_arr: array containing the period of the particle with that index
    Return: 4 tuple containing adjusted max_arr, min_arr, orbit_complete_flags, period_arr
    """

    #apoapsis/periapsis
    for i in range(len(particle_list)):
        sep = Particle3D.separation(particle_list[i],
                                    particle_list[wrt_arr[i]])
        if norm(sep) > max_arr[i]:
            max_arr[i] = norm(sep)
        elif norm(sep) < min_arr[i]:
            min_arr[i] = norm(sep)

    #period
    for i in range(len(particle_list)):
        if not orbit_complete_flags[i]:
            if orbit_complete(particle_list[i], particle_list[wrt_arr[i]]):
                orbit_complete_flags[i] = True
                period_arr[i] = time

    return (max_arr, min_arr, orbit_complete_flags, period_arr)
Пример #3
0
def pairwiseforces(particle1, particle2, re, De, alpha):
    """
    Method to return pairwise forces
    of 2 particles interacting via the
    morse potential.

    :param particle1: 1st Particle3D instance
    :param particle2: 2nd Particle3D instance
    :param re: paramater re
    :param De: parameter De
    :param alpha: parameter alpha
    :return: potential energy of pairwise particles
    """
    #find separation using Particle3D separation
    sep = Particle3D.separation(particle1, particle2)
    #magnitude of separation vector
    r12 = np.linalg.norm(sep)
    #normalized separation vector
    rnorm = sep / r12
    #find constant out front
    L = -alpha * (r12 - re)
    const = 2 * alpha * De * (1 - np.exp(L)) * np.exp(L)
    #const = 2*alpha*De*((1-(np.exp(-alpha*(r12-re))))*(np.exp(-alpha*(r12-re))))
    #find force on particle 1
    f1 = np.multiply(const, rnorm)
    #unsure if return both f1 or just one and inverse in main code
    return f1
Пример #4
0
def pe_lj(particle1,particle2,sigma):
    """
    LJ params for Argon
    epsilon = 119.8 k_B
    sigma = 3.405e-10
    m = 0.03994 kg/mol
    """
    r = np.linalg.norm(Particle3D.separation(particle1,particle2))/sigma
    pe = 4*((r)*10^(-12) - (r)*10^(-6))
    return pe
Пример #5
0
def pe_morse(particle1, particle2, re, de, a):
    """
        Gives the Morse potential energy between particles interacting via the Morse potential
        
        :param re: equilibrium bond distance
        :param de: parameter controlling depth of the potential minimum
        :param a: parameter controlling curvature of the potential minimum (small a -> wide well)
        """
    r12 = np.linalg.norm(Particle3D.separation(particle1, particle2))
    exp = math.exp(-a * (r12 - re))
    pe = de * (((1 - exp)**2) - 1)
    return pe
def force_morse(p1, p2, D, alpha, r_e):
    """
    Method to return the force on a particle
    in a morse potential.
    Force is given by
    F(p1,p2) = (-2*alpha*D*(1-m.exp(-alpha*(r_12-r_e)))*(m.exp(-alpha*(r_12-r_e)))*Particle3D.separation(p1,p2))/r_12

    :param p1: Particle3D instance 1
    :param p2: Particle3D instance 2
    :param D: parameter D from morse potential
    :param alpha: parameter alpha from morse potential
    :param r_e: parameter r_e from morse potential
    :return: force acting on particle p1 due to p2 as Numpy array
    """

    #the magnitude of the particles' separation
    r_12 = np.linalg.norm(Particle3D.separation(p1, p2))
    #the force on p1 due to p2
    force = (-2 * alpha * D * (1 - math.exp(-alpha * (r_12 - r_e))) *
             (math.exp(-alpha *
                       (r_12 - r_e)))) * (1 / r_12) * (Particle3D.separation(
                           p1, p2))
    return force
Пример #7
0
def grav_pot(p1, p2, G):
    """
    Expression for energy potential of two particles due to gravity
    Inputs:
    Particle3D p1: particle 1
    Particle3d p2: particle 2
    float G: simulation specific parameters
    return float: energy potentialx
    """
    G = float(G)
    if p1 == p2:
        return 0
    sep = Particle3D.separation(p1, p2)
    energy = -1 * G * p1.mass * p2.mass / norm(sep)
    return energy
Пример #8
0
def morse_energy(r1, r2, D_e, r_e, alpha):
    """
    Expression for energy potential of two particles due to morse potential
    Inputs:
    Particle3D r1: particle 1
    Particle3d r2: particle 2
    float D_e, r_e, alpha: simulation specific parameters
    return float: energy potential
    """
    D_e, r_e, alpha = float(D_e), float(r_e), float(alpha)
    if r1 == r2:
        return 0
    sep = Particle3D.separation(r1, r2)
    energy = D_e * ((1 - math.exp(-1 * alpha*(norm(sep) - r_e))) ** 2 - 1)
    return energy
Пример #9
0
def morse_force(r1, r2, D_e, r_e, alpha):
    """
    Calculates the force due to the morse potential on particle 1 due to particle 2
    Inputs:
    Particle3D r1: particle 1
    Particle3d r2: particle 2
    float D_e, r_e, alpha: simulation specific parameters
    return numpy array: force
    """
    if r1 == r2:
        return np.array([0,0,0])
    D_e, r_e, alpha = float(D_e), float(r_e), float(alpha)
    sep = Particle3D.separation(r1, r2)
    #Split expression for force into smaller parts for easier digestion
    force_part_one = -2 * alpha * D_e * (1 - math.exp(-1 * alpha * (norm(sep) - r_e)))
    force_part_two = math.exp(-1 * alpha * (norm(sep) - r_e))
    return force_part_one * force_part_two * (sep/norm(sep))
Пример #10
0
def grav_force(p1, p2, G):
    """
    Calculates the force due to gravity on particle 1 due to particle 2
    Inputs:
    Particle3D p1: particle 1
    Particle3d p2: particle 2
    float G: simulation specific parameters
    return numpy array: force
    """
    if p1 == p2:
        return np.array([0, 0, 0])
    G = float(G)
    sep = Particle3D.separation(p1, p2)
    #Split expression for force into smaller parts for easier digestion
    force_part_one = G * p1.mass * p2.mass
    force_part_two = norm(sep)**3
    return -1 * (force_part_one / force_part_two) * (sep)
Пример #11
0
def potenergy(particle1, particle2, re, De, alpha):
    """
    Method to return potential energy
    of 2 particles interacting via
    the morse potential.

    :param particle1: 1st Particle3D instance
    :param particle2: 2nd Particle3D instance
    :param re: paramater re
    :param De: parameter De
    :param alpha: parameter alpha
    :return: potential energy of pairwise particles
    """
    #find separation using Particle3D separation
    sep = Particle3D.separation(particle1, particle2)
    #find potential by finding magnitude of separation and using given eqn
    potential = De * ((1 - np.exp(-alpha * (np.linalg.norm(sep) - re)))**2 - 1)
    return potential
Пример #12
0
def v_verlet(p1, p2, dt, D, alpha, r_e):

    force = force_morse(p1, p2, D, alpha, r_e)

    p1.leap_pos2nd(dt, force)
    p2.leap_pos2nd(dt, -force)

    new_force = force_morse(p1, p2, D, alpha, r_e)

    p1.leap_velocity(dt, 0.5 * (force + new_force))
    p2.leap_velocity(dt, 0.5 * (-force - new_force))

    separ = np.linalg.norm(Particle3D.separation(p1, p2))

    tot_ener = pot_energy_morse(
        separ, D, alpha, r_e) + p1.kinetic_energy() + p2.kinetic_energy()

    return [separ, tot_ener]
Пример #13
0
def main():
    # Read name of output file from command line, 3 arguments;
    #python code, positiontext, and potential values
    if len(sys.argv) != 3:
        print("Wrong number of arguments.")
        print("Usage: " + sys.argv[0] + " <output file>")
        quit()
    else:
        #input files for initial position & potential constants
        inputfile1 = sys.argv[1]
        inputfile2 = sys.argv[2]

    # Open output files separation & total energy
    sep_outfile = open("separationfile.txt", "w")
    u_outfile = open("totalenergyfile.txt", "w")

    # Set up simulation parameters
    dt = float(input("Please determine timestep: "))
    tfinal = 12
    t = 0.0
    tstep = int(tfinal / dt)

    #Open position file
    file_handle = open(inputfile1, "r")

    #Open potential constants file
    file_pot = open(inputfile2, "r")
    #read line of file
    line = file_pot.readline()
    #split file into components at "," within file, should have 4 elements
    components = line.split(" ")
    #convert to floats and separate
    vals = [float(i) for i in components]
    #separate for readability into constants
    De = vals[0]
    re = vals[1]
    alpha = vals[2]
    #NOTE mass is included in the initial positions file, not in here

    #Create particles from initial position files
    p1 = Particle3D.from_file(file_handle)
    p2 = Particle3D.from_file(file_handle)

    # Write out initial conditions, separation & energy
    separ = np.linalg.norm(Particle3D.separation(p1, p2))
    energy = p1.kinetic_energy() + p2.kinetic_energy() + mp.potenergy(
        p1, p2, re, De, alpha)

    u_outfile.write("{},{}\n".format(t, energy))
    sep_outfile.write("{},{}\n".format(t, separ))
    #u_outfile.write("{0:f} {1:f} {2:12.8f}\n".format(time,p1.position,energy))

    # Initialise data lists for plotting later, first points
    time_list = [t]
    sep_list = [separ]
    energy_list = [energy]
    #Print out of important variables
    print(p1)
    print(p2)
    print(separ)
    # Start the time integration loop, with steps being total time over step size
    for i in range(tstep):
        # Update particle positions
        p1.leap_pos1st(dt)
        p2.leap_pos1st(dt)

        # Calculate pairwiseforces
        pairwisef1 = mp.pairwiseforces(p1, p2, re, De, alpha)
        pairwisef2 = -pairwisef1
        # Update particle velocities
        p1.leap_velocity(dt, pairwisef1)
        p2.leap_velocity(dt, pairwisef2)

        # Increase time
        t += dt

        # Output particle information
        #energy
        energy = p1.kinetic_energy() + p2.kinetic_energy() + mp.potenergy(
            p1, p2, re, De, alpha)
        u_outfile.write("{},{}\n".format(t, energy))
        #separation
        separ = np.linalg.norm(Particle3D.separation(p1, p2))
        sep_outfile.write("{}{}\n".format(t, separ))

        # Append information to data lists
        time_list.append(t)
        sep_list.append(separ)
        energy_list.append(energy)

    # Post-simulation:
    # Close output file
    sep_outfile.close()
    u_outfile.close()

    # Plot particle trajectory to screen
    pyplot.title('Symplectic Euler: Separation vs time')
    pyplot.xlabel('Time (10.18fs)')
    pyplot.ylabel('Separation (Angstroms)')
    pyplot.plot(time_list, sep_list)
    pyplot.legend(['Total Separation of the two particles'], loc=2)
    pyplot.show()

    # Plot particle energy to screen
    pyplot.title('Symplectic Euler: total energy vs time')
    pyplot.xlabel('Time (10.18fs)')
    pyplot.ylabel('Energy (eV)')
    pyplot.plot(time_list, energy_list)
    pyplot.legend(['Total energy of the two particles'], loc=2)
    pyplot.show()
Пример #14
0
def main():

    #have the user enter which particle type they want to simulate
    particle_prompt = input(
        "Which particle are you looking to simulate? Type O or N ")

    if particle_prompt == "O":
        p1 = Particle3D.from_file("oxygen1.txt")
        p2 = Particle3D.from_file("oxygen2.txt")
        numstep, time, alpha, r_e, D_e = from_file_system(
            "oxygen_parameters.txt")

    elif particle_prompt == "N":
        p1 = Particle3D.from_file("nitrogen1.txt")
        p2 = Particle3D.from_file("nitrogen2.txt")
        numstep, time, alpha, r_e, D_e = from_file_system(
            "nitrogen_parameters.txt")

    else:
        print("that doesn't look right!")
        exit()

    # have user specify timestep
    dt = input("Enter your preferred timestep: ")
    dt = float(dt)

    pos1 = p1.position
    pos2 = p2.position

    initial_dist12 = Particle3D.separation(p1, p2)

    # finds the initial energy value
    energy = p1.kinetic_energy() + p2.kinetic_energy() + potential(
        initial_dist12, r_e, D_e, alpha)

    # calculate initial force value
    force = force_dw(initial_dist12, r_e, D_e, alpha)
    print(force)

    #initialise data lists for plotting later
    initial_dist12 = np.linalg.norm(initial_dist12)
    time_list = [time * 10.8E-15]
    pos_list = [np.linalg.norm(initial_dist12)]
    energy_list = [energy]

    #start time integration loop

    for i in range(numstep):

        # update time, position and energy values

        time += dt  # time - appended later

        new_pos1 = p1.update_position2(dt, force)
        new_pos2 = p2.update_position2(dt, -force)
        new_dist = np.subtract(new_pos1, new_pos2)
        new_dist_norm = np.linalg.norm(new_dist)
        energy = p1.kinetic_energy() + p2.kinetic_energy() + potential(
            new_dist, r_e, D_e, alpha)

        # append energy and time data values to lists

        energy_list.append(energy)
        time_list.append(time * 10.8E-15)
        pos_list.append(new_dist_norm)

        # assign current velocity to variables

        vel1 = p1.velocity
        vel2 = p2.velocity
        old_force = -force
        force = force_dw(new_dist, r_e, D_e, alpha)
        # update velocity values
        p1.velocity = p1.update_velocity2(dt, old_force, force)
        p2.velocity = p2.update_velocity2(dt, old_force, -force)

    # creates text files to contain energy and relative separation
    outfile_energy = open("VerletEnergy.txt", "w")
    outfile_separation = open("VerletSeparation.txt", "w")

    # for loop writing individual values of energy to file as strings
    for number in energy_list:
        outfile_energy.write(str(number))
    outfile_energy.close()

    # for loop writing individual values of position to file as strings
    for number in pos_list:
        outfile_separation.write(str(number))
    outfile_separation.close()

    frequency(pos_list, time_list)
    energy_vals(energy_list)

    # create two subplots
    fig, axs = plt.subplots(2, 1, constrained_layout=True)
    # plot trajectory to first subplot
    axs[0].plot(time_list, pos_list, '-')
    axs[0].set_title('Time vs. relative position')
    axs[0].set_xlabel('Time')
    axs[0].set_ylabel('Relative Position')
    fig.suptitle('Verlet data', fontsize=16)

    # plot time and energy to second subplot
    axs[1].plot(time_list, energy_list, '-')
    axs[1].set_xlabel('Time')
    axs[1].set_title('Time vs. energy')
    axs[1].set_ylabel('Total Energy')

    plt.show()
Пример #15
0
def main():
    # Read name of input and output files from command line
    if len(sys.argv) != 4:
        print("Wrong number of arguments.")
        print("Usage: " + sys.argv[0] + " <input file> " +
              "<separation output file> " + "<energy output file>")
        quit()
    else:
        datafile_name = sys.argv[1]
        outfile_separation_name = sys.argv[2]
        outfile_energy_name = sys.argv[3]

    # Open files
    outfile_separation = open(outfile_separation_name, "w")
    outfile_energy = open(outfile_energy_name, "w")
    """
    data file should be formated
    x1 y1 z1 Vx1 Vy1 Vz1 mass1 label1
    x2 y2 z2 Vx2 Vy2 Vz2 mass2 label2
    dt time numstep re de a
    """
    datafile = open(datafile_name, "r")

    # Set up particles and simulation parameters
    particle1 = Particle3D.from_file(datafile)
    particle2 = Particle3D.from_file(datafile)

    line = datafile.readline()
    param_data = line.split()
    dt = float(param_data[0])
    time = float(param_data[1])
    numstep = int(param_data[2])
    re = float(param_data[3])
    de = float(param_data[4])
    a = float(param_data[5])

    # Write initial conditions
    separation = np.linalg.norm(Particle3D.separation(particle1, particle2))
    energy = particle1.kinetic_energy() + particle2.kinetic_energy(
    ) + pe_morse(particle1, particle2, re, de, a)
    """
    ::::::FIX FORMAT FOR VMD USE:::::::

    outfile_separation.write("{0:f} , {1:4.4f}\n".format(time,separation))
    outfile_energy.write("{0:f} , {1:4.4f}\n".format(time,energy))
    """

    #Initial force (use '-force' for force on particle2)
    force = force_morse(particle1, particle2, re, de, a)

    # Initialise data lists for plotting
    time_list = [time]
    sep_list = [separation]
    energy_list = [energy]

    # Time integration loop
    for i in range(numstep):
        print('ITERATION ' + str(i + 1) + ':')
        print(str(particle1) + '  ' + str(particle2))
        # Update positions
        particle1.leap_pos2nd(dt, force)
        particle2.leap_pos2nd(dt, -force)

        # Calculate separation
        separation = np.linalg.norm(Particle3D.separation(
            particle1, particle2))

        # Calculate new force
        force_new = force_morse(particle1, particle2, re, de, a)

        # Update velocities with an average of current and new forces
        avg_force = 0.5 * (force + force_new)
        particle1.leap_velocity(dt, avg_force)
        particle2.leap_velocity(dt, -avg_force)

        # Update force value
        force = force_new

        # Update energy
        energy = particle1.kinetic_energy() + particle2.kinetic_energy(
        ) + pe_morse(particle1, particle2, re, de, a)

        # Update time
        time += dt * 10.1805057107594

        # Output information :::::::CLEAN THIS UP:::::::::
        outfile_separation.write(
            str(2) + "\n" + "Point = " + str(i + 1) + "\n" + "s1 " +
            str(particle1.position[0]) + " " + str(particle1.position[1]) +
            " " + str(particle1.position[2]) + "\n" + "s2 " +
            str(particle2.position[0]) + str(particle2.position[1]) +
            str(particle2.position[2]) + "\n")
        outfile_energy.write("{0:f} , {1:4.4f}\n".format(time, energy))

        # Append information to data lists
        time_list.append(time)
        sep_list.append(separation)
        energy_list.append(energy)

    # Close output files
    outfile_separation.close()
    outfile_energy.close()

    # Find the error in the energy
    energy_error = abs((max(energy_list) - min(energy_list)) / energy_list[0])
    print('Error in energy = ' + str(energy_error * 100) + ' %')

    # Find separation peaks and calculate period, frequency and wavenumber
    peak_locations = []
    for i in range((len(sep_list) - 1)):
        if sep_list[i] > sep_list[i + 1] and sep_list[i] > sep_list[i - 1]:
            peak_locations.append(time_list[i])
        else:
            None

    if len(peak_locations) >= 2:
        period = (peak_locations[len(peak_locations) - 1] -
                  peak_locations[0]) / (len(peak_locations) - 1)
        frequency = 1 / (period * 1.0e-15)
        wavenumber = 1 / ((period * 1.0e-15) * 29979245800)
        print('Period = ' + str(period) + 'fs | Frequency = ' +
              str(frequency) + ' Hz | Wavenumber = ' + str(wavenumber) +
              'cm^-1')
    else:
        print(
            'INSUFFICIENT TIME PERIOD. Use a smaller timestep or a larger number of steps'
        )

    # Plots
    pyplot.title('Velocity Verlet: separation vs time')
    pyplot.xlabel('Time /fs')
    pyplot.ylabel('Separation /Å')
    pyplot.grid(which='both', axis='both')
    pyplot.plot(time_list, sep_list, color='purple')
    pyplot.show()

    pyplot.title('Velocity Verlet: energy vs time')
    pyplot.xlabel('Time /fs')
    pyplot.ylabel('Energy /eV')
    pyplot.grid(which='both', axis='both')
    pyplot.plot(time_list, energy_list, color='g')
    pyplot.show()
Пример #16
0
def force_lj(particle1,particle2,sigma):
    r = np.linalg.norm(Particle3D.separation(particle1,particle2))/sigma
    force = 48*(r*10^(-14) - 0.5*r*10^(-8))* Particle3D.separation(particle1,particle2)/sigma
    return force
def main():
    if len(sys.argv) != 3:
        raise ValueError(
            "Incorrect number of parameters!\n usage: {0} <input_file> <output_file>"
            .format(sys.argv[0]))
    in_args = get_input_vars(str(sys.argv[1]))

    out_file_name = str(sys.argv[2])
    out_file = open(out_file_name, 'w')

    particles_list = in_args[2]
    sim_params_list = in_args[0]
    part_params_list = in_args[1]

    numstep = int(sim_params_list[0])
    time = float(sim_params_list[1])
    dt = float(sim_params_list[2])

    D_e = part_params_list[0]
    r_e = part_params_list[1]
    alpha = part_params_list[2]

    tVals = [float(time)]
    sepVals = [
        norm(Particle3D.separation(particles_list[0], particles_list[1]))
    ]
    energVals = [total_energy(D_e, r_e, alpha, particles_list)]
    initEnergy = total_energy(D_e, r_e, alpha, particles_list)
    relEnergyError = [0]

    out_file.write("{0:f} {1:f}\n".format(
        time, norm(Particle3D.separation(particles_list[0],
                                         particles_list[1]))))

    #create initial forces
    for i in particles_list:
        i.prev_force = np.array([0, 0, 0])
        for j in particles_list:
            if i != j:
                i.prev_force = i.prev_force + morse_force(
                    i, j, D_e, r_e, alpha)

    for i in range(numstep):

        step_time(particles_list, part_params_list, dt)
        time = time + dt

        tVals.append(time)
        out_file.write("{0:f} {1:f}\n".format(
            time,
            norm(Particle3D.separation(particles_list[0], particles_list[1]))))
        sepVals.append(
            norm(Particle3D.separation(particles_list[0], particles_list[1])))
        energVals.append(total_energy(D_e, r_e, alpha, particles_list))
        relEnergyError.append(
            energy_error_step(total_energy(D_e, r_e, alpha, particles_list),
                              initEnergy))
    out_file.close()

    #1 in time is 10.18 fs or 1.018x10^-14s
    timescale = 1.018e-14
    tVals = [timescale * t for t in tVals]

    f, axarr = plot.subplots(2)
    axarr[0].plot(tVals, sepVals)
    axarr[0].set_title("Particle Separation")
    #axarr[1].plot(tVals, energVals)
    #axarr[1].set_title("System Energy")
    axarr[1].plot(tVals, relEnergyError)
    axarr[1].set_title("Relative Energy Error")
    #plot.plot(tVals, sepVals)
    #plot.title("Particle Separation Against Time")
    #plot.xlabel("Time (s)")
    #plot.ylabel("Separation (m^-10)")
    plot.show()
Пример #18
0
def main():

    #have the user enter which particle type they wish to simulate
    particle_prompt = input(
        "Which particle are you looking to simulate? Type O or N ")

    if particle_prompt == "O":
        p1 = Particle3D.from_file("oxygen1.txt")
        p2 = Particle3D.from_file("oxygen2.txt")
        # set system parameters
        numstep, time, alpha, r_e, D_e = from_file_system(
            "oxygen_parameters.txt")

    elif particle_prompt == "N":
        p1 = Particle3D.from_file("nitrogen1.txt")
        p2 = Particle3D.from_file("nitrogen2.txt")
        # set system parameters
        numstep, time, alpha, r_e, D_e = from_file_system(
            "nitrogen_parameters.txt")

    else:
        print("that doesn't look right!")
        exit()
    # have user specify timestep
    dt = input("Enter your preferred timestep: ")
    dt = float(dt)

    # finds the initial relative distance of the two particles

    pos1 = p1.position
    pos2 = p2.position
    initial_dist12 = Particle3D.separation(p1, p2)

    # finds the initial energy value
    energy = p1.kinetic_energy() + p2.kinetic_energy() + potential(
        initial_dist12, r_e, D_e, alpha)

    # calculate initial force value

    force = force_dw(initial_dist12, r_e, D_e, alpha)

    #initialise data lists for plotting later
    initial_dist12 = np.linalg.norm(initial_dist12)
    time_list = [time * 10.8E-15]
    pos_list = [initial_dist12]
    energy_list = [energy]

    #start time integration loop

    for i in range(numstep):

        # update everything we're planning to append to a list

        time += dt  # time - appended later

        new_pos1 = p1.update_position1(dt)
        new_pos2 = p2.update_position1(dt)
        new_dist = np.subtract(new_pos1, new_pos2)
        new_dist_norm = np.linalg.norm(new_dist)
        energy = p1.kinetic_energy() + p2.kinetic_energy() + potential(
            new_dist_norm, r_e, D_e, alpha)

        # append energy and time data values to lists

        energy_list.append(energy)
        time_list.append(time * 10.8E-15)
        pos_list.append(new_dist_norm)

        velocity2 = p2.velocity  # defining old velocity for incrementing force

        # update force and velocity values
        force = force_dw(new_dist, r_e, D_e, alpha)
        p1.velocity = p1.update_velocity(dt, force)
        p2.velocity = p2.update_velocity(dt, -force)

        # outwriting energy and time data to external file
    outfile_energy = open("symplecticEnergy.txt", "w")
    outfile_separation = open("symplecticSeparation.txt", "w")
    for number in energy_list:
        outfile_energy.write(str(number))
    outfile_energy.close()
    for number in pos_list:
        outfile_separation.write(str(number))
    outfile_separation.close()

    # find frequency of both measurements
    frequency(pos_list, time_list)
    energy_vals(energy_list)

    # set up axes
    # assign relative position to first subplot
    fig, axs = plt.subplots(2, 1, constrained_layout=True)
    axs[0].plot(time_list, pos_list, '-')
    axs[0].set_title('Symplectic: time vs. relative position')
    axs[0].set_xlabel('time')
    axs[0].set_ylabel('Relative Position')
    fig.suptitle('Symplectic data', fontsize=16)

    # assign energy to first subplot
    axs[1].plot(time_list, energy_list, '-')
    axs[1].set_xlabel('time[10.8*10^{-2}s]')
    axs[1].set_title('Symplectic: time vs. energy')
    axs[1].set_ylabel('Total Energy')

    plt.show()
Пример #19
0
def main():
    # Read name of output file from command line
    if len(sys.argv) != 3:
        print("Wrong number of arguments.")
        print("Usage: " + sys.argv[0] + " <output file>")
        quit()
    else:
        #input files for initial position & potential constants
        inputfile1 = sys.argv[1]
        inputfile2 = sys.argv[2]

    # Open output files separation & total energy
    sep_outfile = open("separationfile.txt", "w")
    u_outfile = open("totalenergyfile.txt", "w")

    # Set up simulation parameters
    dt = float(input("Please determine timestep: "))
    tfinal = 10
    t = 0.0
    tstep = int(tfinal / dt)

    #open position file
    file_handle = open(inputfile1, "r")

    #Open potential constants file
    file_pot = open(inputfile2, "r")
    #read line of file
    line = file_pot.readline()
    #split file into components at "," within file, should have 4 elements
    components = line.split(" ")
    #convert to floats and separate
    vals = [float(i) for i in components]
    #separate for readability into constants
    De = vals[0]
    re = vals[1]
    alpha = vals[2]
    #NOTE mass is included in the initial positions file, not in here

    #Create particles from initial position files
    p1 = Particle3D.from_file(file_handle)
    p2 = Particle3D.from_file(file_handle)

    # Write out initial conditions, separation & energy
    separ = np.linalg.norm(Particle3D.separation(p1, p2))
    energy = p1.kinetic_energy() + p2.kinetic_energy() + mp.potenergy(
        p1, p2, re, De, alpha)

    u_outfile.write("{},{}\n".format(t, energy))
    sep_outfile.write("{},{}\n".format(t, separ))

    #Find pairwiseforces
    pairwisef1 = mp.pairwiseforces(p1, p2, re, De, alpha)
    pairwisef2 = -pairwisef1

    # Initialise data lists for plotting later, first points
    time_list = [t]
    sep_list = [separ]
    energy_list = [energy]
    #Print out of important variables
    print(p1)
    print(p2)
    print(separ)

    # Start the time integration loop
    for i in range(tstep):
        # Update particle position
        p1.leap_pos2nd(dt, pairwisef1)
        p2.leap_pos2nd(dt, pairwisef2)

        #new forces
        prwsf1 = mp.pairwiseforces(p1, p2, re, De, alpha)
        prwsf2 = -prwsf1
        # Update particle velocity by averaging
        # current and new forces
        p1.leap_velocity(dt, 0.5 * (pairwisef1 + prwsf1))
        p2.leap_velocity(dt, 0.5 * (pairwisef2 + prwsf2))

        # Re-define force value
        pairwisef1 = prwsf1
        pairwisef2 = prwsf2

        # Increase time
        t += dt

        # Output particle information
        #energy
        energy = p1.kinetic_energy() + p2.kinetic_energy() + mp.potenergy(
            p1, p2, re, De, alpha)
        u_outfile.write("{},{}\n".format(t, energy))
        #separation
        separ = np.linalg.norm(Particle3D.separation(p1, p2))
        sep_outfile.write("{}{}\n".format(t, separ))

        # Append information to data lists
        time_list.append(t)
        sep_list.append(separ)
        energy_list.append(energy)

    # Post-simulation:
    # Close output file
    sep_outfile.close()
    u_outfile.close()

    # Plot particle trajectory to screen
    pyplot.title('Velocity Verlet: Separation vs time')
    pyplot.xlabel('Time')
    pyplot.ylabel('Separtion')
    pyplot.plot(time_list, sep_list)
    pyplot.show()

    # Plot particle energy to screen
    pyplot.title('Velocity Verlet: total energy vs time')
    pyplot.xlabel('Time')
    pyplot.ylabel('Energy')
    pyplot.plot(time_list, energy_list)
    pyplot.show()