Пример #1
0
            def apply(self, particle: Particle, other_particle: Particle,
                      engine: "Engine") -> Dict[str, Set[Particle]]:
                if particle.mass > other_particle.mass:
                    particle, other_particle = other_particle, particle
                if (other_particle
                        not in engine.features["remove"].particles_to_remove
                        and compute_multi_dimensional_distance(
                            particle.position, other_particle.position) < umd
                        # < other_particle.compute_size() + particle.compute_size()
                    ):
                    total_mass = particle.mass + other_particle.mass
                    p_share = particle.mass / total_mass
                    o_share = other_particle.mass / total_mass
                    # todo : Move position to the weighted mean of the two particles
                    other_particle.delay_update("_mass", total_mass)
                    # noinspection PyProtectedMember
                    other_particle.delay_update(
                        "_velocity",
                        [
                            p_velocity * p_share + o_velocity * o_share
                            for p_velocity, o_velocity in zip(
                                particle._velocity, other_particle._velocity)
                        ],
                    )
                    particles_to_remove = {particle}
                else:
                    particles_to_remove = {}

                return {"remove": particles_to_remove}
Пример #2
0
 def _loop(self):
     particle = Particle(Vector(WIDTH / 2, 0, 0), Vector(0, 0, 0),
                         Vector(0, 10e-4, 0), 0.99, 10)
     self.clock.tick()
     while True:
         tick = self.clock.tick()
         particle.integrate(tick)
         self._draw(particle)
Пример #3
0
    def _create_particles_and_constraints(self) -> None:
        for name, segment in TURKEY_SEGMENTS.items():
            # scale the points up.
            scaled_points = np.asarray(segment, float) * self.scale
            self.segments[name] = []
            for p in scaled_points:
                # find the particle if it already exists, otherwise create a new one.
                particle: Particle = next((part for part in self.particles
                                           if np.allclose(part.curr_pos, p)),
                                          Particle(position=p,
                                                   mass=Turkey.mass))
                if particle not in self.particles:
                    self.particles.append(particle)
                # print("adding a new particle at ", particle.curr_pos)
                # print(len(self.particles))
                # append the particle to this segment.
                self.segments[name].append(particle)

            if name == "eye":
                continue

            # create a Stick constraint for each pair within this segment.
            for p1, p2 in pairs(self.segments[name]):
                constraint = StickConstraint(p1, p2, relatice_tolerance=0.1)
                self.stick_constraints.append(constraint)

            # add more flexible stick constraints between every other node on this segment:
            for p1, p2 in pairs(self.segments[name][::2]):
                constraint = StickConstraint(p1, p2, relatice_tolerance=0.4)
                self.stick_constraints.append(constraint)
Пример #4
0
 def manage_particle_interaction(self, particle_1: Particle,
                                 particle_2: Particle):
     for law in self.arbitrary_laws:
         output = law.apply(particle_1, particle_2, self)
         for feature_name, data in output.items():
             self.features[feature_name].update(data)
     total_force = None
     for force_generator in self.force_generators:
         force = force_generator.compute_force(particle_1, particle_2)
         if total_force is None:
             total_force = force
         for dimension, (dimensional_total_force,
                         dimensional_force) in enumerate(
                             zip(total_force, force)):
             total_force[
                 dimension] = dimensional_total_force + dimensional_force
     particle_1.apply_force(total_force, particle_2)
     particle_1.run()
Пример #5
0
def create_world():
    w = World((2000, 2000))
    n_particles = 20
    vmax = 100
    for _ in range(n_particles):
        pos = random.randint(0, w.rect.w), random.randint(0, w.rect.h)
        s = random.uniform(-vmax, vmax), random.uniform(-vmax, vmax)
        m = 1.
        w.add_particle(Particle(Vector2(pos), Vector2(s), m))
    return w
Пример #6
0
def asteroids():
    particle1 = Particle(q0x=R,
                         q0y=0,
                         p0x=0,
                         p0y=29.29 * 1e3 * Mear,
                         m=Mear,
                         name="Earth")
    particle2 = Particle(0, 0, 0, 0, m=Msol, fixed=True, name="Sun")

    asteroid_v_angles = []
    earth_vangles = []
    initial_vangles = np.array([45, 40, 30, 20, 15, 10, 5]) * math.pi / 180
    masses = np.array([
        1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1, 2e1, 5e1, 1e2, 3e2, 5e2, 7e2,
        1e3
    ])
    # masses = np.array([1e0])

    ivangle = math.pi / 2
    # mass=
    # norm(self.px, self.py)**2/self.m/2
    eccentricitiesEar = []
    eccentricitiesAst = []
    for i, mass in enumerate(masses):
        pabs = 10 * 1e3 * mass * Mear
        timefactor = 1.1
        plotstuff = False
        # if mass == 3e2:
        #     timefactor=1
        #     plotstuff=True
        particle3 = Particle(q0x=R * (1 - 0.001),
                             q0y=0.1 * R,
                             p0x=pabs * math.cos(ivangle),
                             p0y=-pabs * math.sin(ivangle),
                             m=mass * Mear,
                             name="Massive asteroid")
        # particle3 = Particle(q0x=-R, q0y=0, p0x=0, p0y=-29.29*1e3*Mear, m=Mear, name="Massive asteroid")

        parcls = [particle1, particle2, particle3]
        initstate = InitialState(parcls)
        system = System(initstate.get_state(),
                        SymplecticEuler,
                        tmax=TMAX * timefactor,
                        dt=100,
                        stepsperframe=400)
        system.simulate()
        # system.animate(boxlimits=1.5*R, interval=20)
        eccentricitiesEar.append(system.eccentricity(0))
        try:
            eccentricitiesAst.append(system.eccentricity(2))
        except ValueError:
            print("Negative asteroid eccentricity")
        if plotstuff:
            system.plot_trajectories(show=False, new_fig=not i)
        # system.plot_energies()
        vangleAst = math.atan(
            system.particles[2].py / system.particles[2].px) / math.pi * 180
        vangleEar = math.atan(
            system.particles[0].py / system.particles[0].px) / math.pi * 180
        earth_vangles.append(vangleEar)
        asteroid_v_angles.append(vangleAst)

    # particles[0].name="Undisturbed Earth"
    # initstate = InitialState(particles)
    # system = System(initstate.get_state(), SymplecticEuler, tmax=TMAX*timefactor, dt=100, stepsperframe=400)
    # system.simulate()
    # system.plot_trajectory(0,show=True,new_fig=False)

    plt.figure()
    plt.plot(masses, asteroid_v_angles, '-')
    plt.xscale("log")
    plt.title("Asteroid's velocity angle after Earth slingshot")
    plt.xlabel("$Asteroid\ mass\ [M⊕]$")
    plt.ylabel("Angle [degrees]")
    plt.show()

    plt.figure()
    plt.plot(masses, earth_vangles, '-')
    plt.title("Earth's velocity angle after massive asteroid slingshot")
    plt.xscale("log")
    plt.ylabel("Angle [degrees]")
    plt.xlabel("$Asteroid\ mass\ [M⊕]$")
    plt.show()

    plt.figure()
    plt.title("Earth's orbital eccentricity after massive asteroid slingshot")
    plt.plot(masses, eccentricitiesEar, '-')
    plt.xscale("log")
    plt.xlabel("$Asteroid\ mass\ [M⊕]$")
    plt.ylabel("$eccentricity$")
    plt.show()

    plt.figure()
    plt.title("Asteroids's orbital eccentricity after Earth slingshot")
    plt.plot(masses, eccentricitiesAst, '-')
    plt.xscale("log")
    plt.xlabel("$Asteroid\ mass\ [M⊕]$")
    plt.ylabel("$eccentricity$")
    plt.show()
Пример #7
0
import numpy as np
from matplotlib import pyplot as plt

from physics import Particle, System, InitialState
from Integrators import SymplecticEuler, Leapfrog, RungeKutta4, ForwardEuler
from constants import G

# a=0.5
R = 152 * 1e9
Msol = 1.9891e30
Mear = 5.972e24
TMAX = 60 * 60 * 24 * 365 * 1

particle1 = Particle(q0x=R,
                     q0y=0,
                     p0x=0,
                     p0y=29.29 * 1e3 * Mear,
                     m=Mear,
                     name="Earth")
particle2 = Particle(0, 0, 0, 0, m=Msol, fixed=False, name="Sun")
particles = [particle1, particle2]
initial_state = InitialState(particles)


def compare_integrators():
    integrators = [ForwardEuler, SymplecticEuler, Leapfrog, RungeKutta4]
    timesteps = [10000000, 1000000, 100000, 10000, 1000, 100]

    errors = np.zeros((len(integrators), len(timesteps)))
    energy_drifts = np.zeros((len(integrators), len(timesteps)))
    energy_drifts_at_tmax = np.zeros((len(integrators), len(timesteps)))
    for i, integrator in enumerate(integrators):
Пример #8
0
def test_visualize():
    particles = [Particle(0.3, 0.5, 1),
                 Particle(0.0, -0.5, -1),
                 Particle(-0.1, -0.4, 3)]
    simulator = ParticleSimulator(particles)
    visualize(simulator)