def _calculate_vs_and_ps(radiiA, num_particlesB, **kwargs): """ Calculate vs and ps""" particles = [] co = scl.Controls() # the controls really don't matter in this instance. countA = 0 for i in range(len(radiiA)): countB = 0 # CountB is number in a Particular Ring for j in range(num_particlesB[i]): countA += 1 countB += 1 if radiiA[i] == 0: particles.append( hal.Particle( np.array([0.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0]), 1.0, True, countA, ) ) else: pos = hlp.circular_position(radiiA[i], num_particlesB[i], j) vel = hlp.circular_velocity(radiiA[i], num_particlesB[i], j, co) particles.append(hal.Particle(pos, vel, 1.0, False, countA)) return particles
def three_body_collide( MAX_TIMER=600, VB=10, TSTEP=0.05, EP=0.01, recalculate=True, algorithm="vv", **kwargs ): """ Runs a three body collision to look check other functions. """ particles = [] sub = str(MAX_TIMER) + "t_" + str(EP) + "e_" + str(TSTEP) + "dt_" + str(algorithm) co = scl.Controls( MAXTIMER=MAX_TIMER, TSTEP=TSTEP, vb=VB, halo=False, EPS=EP, OUT="./TBP_TEST/" + sub, calculate_am=True, algorithm=algorithm, ) sy = scl.System(co, particles=particles) name = "TBP" + sub co.name = name if recalculate: particles = three_particle_adder(co, particles) sy = scl.System(co, particles=particles) middle_manager(co, sy, name, particles=particles, recalculate=recalculate)
def acc_fun_plotter(): """ A function designed to plot the gravitational field around a central particle""" co = scl.Controls(EPS=0.01) x_values = np.linspace(0, 25, num=2000) # x_lim = [-0.1 10] x_lim = [-0.1, 25] a_values = [] # radii = [0.1, 0.2, 0.3, 0.5] radii = [6, 7, 8, 0.1] for radius_index in range(len(radii)): a_values.append([]) test_particle = [ hal.Particle( np.array([0, 0, 0]), np.array([0, 0, 0]), 1.0, True, 0, halo=True, radius=radii[radius_index], ) ] for x in x_values: pos = np.array([x, 0, 0]) acc_vec = -hal.acc_fun(-1, pos, test_particle, co) a_values[radius_index].append(acc_vec[0]) plt.plot( x_values, a_values[radius_index], LineWidth=0.5, label="Halo with radius " + str(radii[radius_index]), ) y_lim = [-0.005, 1.4 * (np.max(a_values[0]))] plt.ylim(y_lim) plt.gca().invert_xaxis() # this command seems to do absolutely nothing :/ plt.ylabel(r"Attractive Acceleration") plt.xlabel(r"Separation Distance") plt.xlim(x_lim) plt.legend() plt.tight_layout() # plt.savefig('Gen_Output/Test_Halo_Forces.pdf') plt.savefig("Gen_Output/Dark_vs_Light.pdf") plt.clf()
def many_body_collide( MAX_TIMER=600, VB=1000, TSTEP=0.0001, EP=0.01, recalculate=True, algorithm="vv" ): """ Runs a multi body collision to look check other functions. """ particles = [] sub = str(MAX_TIMER) + "t_" + str(EP) + "e" co = scl.Controls( MAXTIMER=MAX_TIMER, TSTEP=TSTEP, vb=VB, halo=False, EPS=EP, OUT="./MBP_TEST/" + sub, calculate_am=True, algorithm=algorithm, ) sy = scl.System(co, particles=particles) name = "MBP" + sub co.name = name p = [ [0.0, 0.0, 0.0], [0.0, 5.0, 0.0], [0.0, -5.0, 0.0], [5.0, 0.0, 0.0], [-5.0, 0.0, 0.0], ] v = [ [0.0, 0.0, 0.0], [0.5, -0.2, 0.0], [-0.5, 0.2, 0.0], [-0.2, 0.5, 0.0], [-0.2, 0.5, 0.0], ] m = [1, 1, 1, 1, 1] if recalculate: particles = arbitrary_particle_adder( co, particles, pos_list=p, vel_list=v, mass_list=m ) sy = scl.System(co, particles=particles) middle_manager(co, sy, name, particles=particles, recalculate=recalculate)
def two_body_circle( MAX_TIMER=600, VB=10, TSTEP=0.05, EP=0.01, recalculate=True, algorithm="vv" ): """Makes two bodies of equal mass circle round each other, for a long time to check any errors that might be extant in the functions""" co = scl.Controls( MAXTIMER=MAX_TIMER, TSTEP=TSTEP, vb=VB, halo=False, EPS=EP, OUT="./Algo_Comp/", calculate_am=True, algorithm=algorithm, ) particles = [] p = [[1, 0, 0], [-1, 0, 0]] v = [[0, 1, 0], [0, -1, 0]] m = [1, 1] arbitrary_particle_adder(co, particles, pos_list=p, vel_list=v, mass_list=m)
def _circular_orbit(seperation=2, algo="vv", tstep=0.05): """ Take the desired seperation between the two equally sized masses, and turn that into a list of two particles at the right speed and distance. """ co = scl.Controls( MAXTIMER=20, TSTEP=tstep, algorithm=algo, OUT="MUT_CIRC", name=algo + "_" + str(tstep), ) speed = np.sqrt(co.GM / 2 / seperation) particles = [] particles.append( hal.Particle( np.array([-seperation / 2, 0, 0]), np.array([0, speed, 0]), 1.0, False, countA, ) ) particles.append( hal.Particle( np.array([-seperation / 2, 0, 0]), np.array([0, speed, 0]), 1.0, False, countA, ) ) tmp_log_data = {} co, sy, particles = spinner(co, sy, particles, log_time=tmp_log_data) time_taken = tmp_log_data["SPINNER"] hlp.write_out(co, sy) return time, energy, time_taken
def galaxy_collide( MAX_TIMER=600, VB=10, TSTEP=0.05, EP=0.01, x00=-15.0, y00=30, m0=0.2, radii=[2, 3, 4, 5], num_particles=[12, 18, 25, 30], recalculate=True, FILE_DIR="./EP_TEST/", halo=False, algorithm="vv", animate=False, **kwargs ): """ Creates the initial galaxies and collision courses, and then hands over to the middle manager. """ particles = [] # create a default empty list to pass about sub = ( str(MAX_TIMER) + "t_" + str(x00) + "x0_" + str(y00) + "y0_" + str(m0) + "m_" + str(EP) + "e_" + "Halos" + str(halo) ) co = scl.Controls( MAXTIMER=MAX_TIMER, TSTEP=TSTEP, vb=VB, halo=halo, EPS=EP, OUT=FILE_DIR + sub, calculate_am=False, algorithm=algorithm, ) for clock in [False, True]: if clock: name = "Retrograde" + sub else: name = "Prograde" + sub sy = scl.System(co, particles=particles) co.name = name if recalculate: particles = galaxy_creator( co, clock, radii=radii, num_particles=num_particles ) particles = impactor_adder(particles, x0=x00, y0=y00, mass=m0) particles = hal.zmf_transform(particles) sy = scl.System(co, particles=particles) middle_manager( co, sy, name, particles=particles, recalculate=recalculate, animate=animate )
def particle_build_up(OM=5): """A function which gradually fills up a galaxy with a variable number particles, trying each algorithm used in the simulation, allowing computational excess to be compared""" # Fills up the shells at these radii to these maximums radii = [ 0, 1.0, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, ] num_particles = [ 1, 12, 18, 24, 31, 36, 42, 50, 58, 70, 80, 100, 130, 160, 200, 250, 300, 340, 400, ] total_particles = 0 for i in num_particles: total_particles += i print("You can go up to " + str(total_particles) + " if you want to.") N_vec = np.logspace(1, OM, num=OM, base=2) # variables to store the raw data tot_particles_d = {} fill_up_time = [] ani_time = [] spin_round_time = {} spinner_time = {} spin_round_time["vv"] = [] spin_round_time["rk4o"] = [] spin_round_time["herm"] = [] spinner_time["vv"] = [] spinner_time["rk4o"] = [] spinner_time["herm"] = [] tot_particles_d["vv"] = [] tot_particles_d["FU"] = [] tot_particles_d["herm"] = [] tot_particles_d["rk4o"] = [] tot_particles_d["ANI"] = [] tot_particles_d["vv_spin"] = [] tot_particles_d["rk4o_spin"] = [] tot_particles_d["herm_spin"] = [] for required_total in N_vec: tmp_log_data = {} # particles = [] particles = _fill_up( radii, num_particles, int(required_total), log_time=tmp_log_data ) if not required_total == N_vec[0]: # The first data point is always terrible and messes up the fit fill_up_time.append(tmp_log_data["_FILL_UP"]) tot_particles_d["FU"].append(len(particles)) print( "There are " + str(len(particles)) + " particles and I expected " + str(required_total) ) # What happens if you just spin the particles? for key in spin_round_time: tot_particles_d[key].append( len(particles) ) # how many particles in this key co = scl.Controls(TSTEP=0.05, algorithm=key) tmp_log_data = {} part = hal.spin_forward( 400, co, particles=copy.deepcopy(particles), log_time=tmp_log_data ) # chuck it into part to stop interference. assert part != particles spin_round_time[key].append(tmp_log_data["SPIN_FORWARD"]) # What happens if you spin the particles, calculate energies, and plot things? for key in spinner_time: tot_particles_d[key + "_spin"].append(len(particles)) sub = key + "_running_time_test_" + str(len(particles)) co = scl.Controls( OUT="./Run_Time_TEST/" + sub, MAXTIMER=400, TSTEP=0.05, algorithm=key, name=sub, ) sy = scl.System(co, particles=particles) tmp_log_data = {} co, sy, part = hal.spinner( co, sy, copy.deepcopy(particles), log_time=tmp_log_data ) # chuck it into part to stop interference. assert part != particles spinner_time[key].append(tmp_log_data["SPINNER"]) # extract spinner time # What about the animation of those particles? hlp.write_out(co, sy) aniclass_member = ani.AniMP4(co.out, name=co.name, move_with=True) # initiate animator animate = True if key == "vv" and animate == True: tmp_log_data = {} aniclass_member.animate_starter(log_time=tmp_log_data) # run animation / plots ani_time.append(tmp_log_data) tot_particles_d["ANI"].append(len(particles)) sy = [] # delete sy so that it doesn't slow the other steps down. save_data = { "tot_particles_d": tot_particles_d, "fill_up_time": fill_up_time, "spin_round_time": spin_round_time, "spinner_time": spinner_time, "ani_time": ani_time, } name = "Fill_Up_Dict_No_Fits_OM_" + str(OM) ip.print_dict_to_pickle(name=name, dictionary=save_data) print("about to go to _fit_fill_up with name " + name) _fit_fill_up(name=name, animate=animate)