def create_body_objects(directory, index=-1): masses = of.get_single_data(directory + "/masses.csv") pos_x = of.get_single_data(directory + "/pos_x.csv")[index] pos_y = of.get_single_data(directory + "/pos_y.csv")[index] pos_z = of.get_single_data(directory + "/pos_z.csv")[index] vel_x = of.get_single_data(directory + "/vel_x.csv")[index] vel_y = of.get_single_data(directory + "/vel_y.csv")[index] vel_z = of.get_single_data(directory + "/vel_z.csv")[index] # Generating and storing all body objects in an array for easy access body_list_create = [] for index, mass in enumerate(masses): mass = int(abs(mass)) pos = np.array([pos_x[index], pos_y[index], pos_z[index]], dtype="int64") vel = np.array([vel_x[index], vel_y[index], vel_z[index]], dtype="int64") temp_body = body_class(mass, pos, vel) body_list_create.append(temp_body) return body_list_create
def simulate(destination_directory, CONT_PREVIOUS=False, save_suffix="", init_conds_name="/init_conds.txt", init_conds_directory="", source_directory="", report_pos=100): """ destination_directory = directory to save results to CONT_PREVIOUS = Continue from previous run (must be stored in destination_directory save_suffix = Use to save multiple runs in the same direcory (outdated - leave blank) init_conds_name = select the initial conditions file source_directory = location of files for continuing previous run - leave blank if same as destination_directory report_pos = Number of time steps between updating the save file """ # Saving "init_conds.txt" to results directory if not os.path.isdir(destination_directory): os.mkdir(destination_directory) source_cp = "cp " + init_conds_directory + init_conds_name os.popen(source_cp + " " + destination_directory + init_conds_name) if not CONT_PREVIOUS: # Generating the cluster from given initial conditions cluster_list = of.generate_full_filament(destination_directory, init_conds_directory, init_conds_name) num_to_strip = 0 # clean data by removing trailing points # Saving init_conds to file cluster_text = "/cluster.csv" file_loc = destination_directory + cluster_text np.savetxt(file_loc, cluster_list, delimiter=",") # Loading in data masses, rx, ry, rz, vx, vy, vz = of.get_data_ready( file_loc, num_to_strip) N = len(masses) # Getting number of bodies elif CONT_PREVIOUS: masses = of.get_single_data(source_directory + "/masses.csv") rx = of.get_single_data(source_directory + "/pos_x.csv") ry = of.get_single_data(source_directory + "/pos_y.csv") rz = of.get_single_data(source_directory + "/pos_z.csv") vx = of.get_single_data(source_directory + "/vel_x.csv") vy = of.get_single_data(source_directory + "/vel_y.csv") vz = of.get_single_data(source_directory + "/vel_z.csv") N = len(masses) # ============================================================================= # Main body # ============================================================================= # %% # Initialising variables/arrays dt = 10 # Time step t = 0 Tmax = 2e14 count = 0 eps = 1e9 r_min = [1e50, 1e50, 1e50] # Arbitrary value > minimum body seperation momentum, kinetic, potential, energy = [[] for _ in range(4)] pos_x, pos_y, pos_z = ([[] for _ in range(N)] for i in range(3)) vel_x, vel_y, vel_z = ([[] for _ in range(N)] for i in range(3)) r_array, dt_array, percent, time_count, time_to_run, sim_time = [ [] for _ in range(6) ] ax, ay, az, r_min = of.get_accel_soft(N, rx, ry, rz, masses, r_min, eps) # Starting main loop and timer start = time.time() while t <= Tmax: # Loop until close program\ # Using a_0 to calculate vel(t + dt/2) and pos(t + dt/2) vx[:] += 0.5 * (ax[:]) * dt vy[:] += 0.5 * (ay[:]) * dt vz[:] += 0.5 * (az[:]) * dt # pos(t + dt) rx[:] += vx[:] * dt ry[:] += vy[:] * dt rz[:] += vz[:] * dt # Update acceleration to a(t + dt) ax, ay, az, r_temp = of.get_accel_soft(N, rx, ry, rz, masses, r_min, eps) # Scaling the softening paramter #eps_temp = of.get_mag(r_temp) #eps = eps_temp if eps_temp > 1e9 else 1e9 # Calculating v(t + dt) vx[:] += 0.5 * (ax[:]) * dt vy[:] += 0.5 * (ay[:]) * dt vz[:] += 0.5 * (az[:]) * dt # Save data to file at certain intervals if count % report_pos == 0: pos_x, pos_y, pos_z, vel_x, vel_y, vel_z, Ek, Ep, Mom = ( of.report_snapshot(t, Tmax, masses, vx, vy, vz, rx, ry, rz, N, pos_x, pos_y, pos_z, vel_x, vel_y, vel_z, eps)) # To get percentage displayed: # -> uncomment the print line of of.get_completion() # -> Set a Tmax outside of loop percent = of.get_completion(t, Tmax, percent) Et = Ek + Ep kinetic.append(Ek) potential.append(Ep) momentum.append(Mom) energy.append(Et) dt_array.append(dt) of.save_interval(masses, pos_x, pos_y, pos_z, vel_x, vel_y, vel_z, destination_directory, index=save_suffix) np.savetxt(destination_directory + "/kinetic.csv", kinetic) np.savetxt(destination_directory + "/potential.csv", potential) np.savetxt(destination_directory + "/momentum.csv", momentum) end = time.time() time_to_run.append(end - start) sim_time.append(t) np.savetxt(destination_directory + "/run_time.csv", time_to_run) np.savetxt(destination_directory + "/sim_time.csv", sim_time) np.savetxt(destination_directory + "/time_step.csv", dt_array) # Closest approach calculations and storing R_min = of.get_mag(r_min) R_temp = of.get_mag(r_temp) if R_temp < R_min: r_min = r_temp R_min = of.get_mag(r_min) r_array.append(R_min) # Dynamic time step calculation accel = [] for i, _ in enumerate(ax): accel.append(of.get_mag([ax[i], ay[i], az[i]])) a_max = max(accel) dt = np.sqrt(2 * 0.66 * eps / a_max) # eps = (3/4)*max(a)*dt**2 # Incrementing relevant counters time_count.append(t) t += dt count += 1
#run_name = ["1x5_standard"] total_body_list = [] binary_list = [] #body_list = detect_binaries(run_name, 0) for run in run_name: print(run) df.body_class.ID = 0 binary_index = {} binaries = [] body_list = [] pairs = {} sorted_pairs = [] sorted_pairs_fixed = [] direc = "./results/" + run #body_list, binary_index = detect_binaries(run, -1) x = of.get_single_data(direc + "/pos_x.csv") y = of.get_single_data(direc + "/pos_y.csv") z = of.get_single_data(direc + "/pos_z.csv") vx = of.get_single_data(direc + "/vel_x.csv") vy = of.get_single_data(direc + "/vel_y.csv") vz = of.get_single_data(direc + "/vel_z.csv") pairs, body_list = df.new_detect_binaries(run, -1) sorted_pairs = sorted(pairs.items(), key=lambda kv: kv[1]) sorted_pairs_fixed = sorted_pairs[::2] for body in body_list: total_body_list.append(body) for pair in sorted_pairs_fixed: target_ID = pair[0] potential = pair[1]
def make_gif(run_name, num_frames, binary_to_plot=[], plot_pos=1, display="", x_dist=1e16, start=0, save_dir=""): run_dir = "./results/" direc = run_dir + run_name global x x = of.get_single_data(direc + "/pos_x.csv") y = of.get_single_data(direc + "/pos_y.csv") z = of.get_single_data(direc + "/pos_z.csv") x, y, z = of.strip_trailing_data(x, y, z) init_vars = of.get_init_conds(direc + "/init_conds.txt") N = int(init_vars[1]) N_cluster = int(init_vars[0]) #colors_list = list(colors._colors_full_map.values()) colors_list = list(["Blue", "Green", "Fuchsia", "black", "olive"]) fig = plt.figure() p1 = Axes3D(fig) p1.view_init(elev=28, azim=-65) #p1.dist=4 plt.ioff() if display == "True": p1.set_xlim3d(0, x_dist) p1.set_ylim3d(-x_dist / 2, x_dist / 2) p1.set_zlim3d(-x_dist / 2, x_dist / 2) elif display == "All": p1.set_xlim3d(of.min_max(x)) p1.set_ylim3d(of.min_max(y)) p1.set_zlim3d(of.min_max(z)) elif display == "Custom": p1.set_xlim3d(0e16, 2e16) p1.set_ylim3d(-0.5e16, 1.5e16) p1.set_zlim3d(-0.5e16, 1e16) # Selecting frames num_points = len(x) frame_freq = int(num_points / num_frames) frames = [frame_freq * index for index in range(num_frames)] for frame in frames: for j in range(N_cluster): # looping through cluster index #col = random.choice(colors_list) col = "blue" #for i, col in zip([4, 10, 13, 17], ["blue", "red", "red", "black"]): for i in range(len(x[0])): # looping through bodies index if (i >= N * j and i < N * (j + 1)) or (j == 0 and i == 0): if frame < frame_freq: if i in binary_to_plot: p1.plot(x[:frame, i], y[:frame, i], z[:frame, i], color="red", linewidth=0.8) else: p1.plot(x[:frame, i], y[:frame, i], z[:frame, i], color=col, linewidth=0.5, alpha=0.5) else: if i in binary_to_plot: p1.plot(x[(frame - frame_freq):frame, i], y[(frame - frame_freq):frame, i], z[(frame - frame_freq):frame, i], color="red", linewidth=0.8) #p1.scatter(x[0, i], y[0, i], z[0, i], color="red", marker="x") else: p1.plot(x[(frame - frame_freq):frame, i], y[(frame - frame_freq):frame, i], z[(frame - frame_freq):frame, i], color=col, linewidth=0.5, alpha=0.5) #p1.scatter(x[frame, i], y[frame, i], z[frame, i], color=col, marker=".") else: pass fig = plt.savefig(f"./{save_dir}{run_name}{frame}.png") print(f"Frame number {int(frame/frame_freq)}/{num_frames}...")