Esempio n. 1
0
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
Esempio n. 2
0
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)
Esempio n. 3
0
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()
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
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
Esempio n. 7
0
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
        )
Esempio n. 8
0
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)