예제 #1
0
def inelastic_particles(particle0: Particle, particle1: Particle, dt: float):
    """
    TODO extending for moveable walls
    Determines the resulting velocity of a set of colliding particles with mid-fram correction
    :param particle0: First particle in the collision
    :param particle1: Second particle in the collision
    """

    # Determine mass ratios
    mass_ratio0 = 2 * particle1.mole.mass / (particle0.mole.mass + particle1.mole.mass)
    mass_ratio1 = 2 * particle0.mole.mass / (particle0.mole.mass + particle1.mole.mass)

    # generate relative terms
    X = particle0.x - particle1.x
    U = particle1.u - particle0.u
    R = particle0.mole.radius + particle1.mole.radius

    a = np.dot(U, U)
    b = 2*np.dot(X, U)
    c = np.dot(X, X) - R*R

    # Determine time of collision
    dt0 = (-b + np.sqrt(b*b - 4*a*c))/(2*a)

    x0 = particle0.x - particle0.u*dt0
    x1 = particle1.x - particle1.u*dt0

    u0 = particle0.u
    u1 = particle1.u

    # Direction magnitude
    dir_mag = np.dot(u0 - u1, x0 - x1) / (np.dot(x0 - x1, x0 - x1))
    dir_vec = (x0 - x1)

    # Set new velocities
    particle0.u -= mass_ratio0 * dir_mag * dir_vec
    particle1.u -= mass_ratio1 * dir_mag * -dir_vec

    # Correct positions
    particle0.x = x0 + particle0.u * dt0
    particle1.x = x1 + particle1.u * dt0
예제 #2
0
def inelastic_wall(wall: Wall, particle: Particle, dt: float):
    """
    TODO extending for moveable walls
    Determines the resulting velocity of a particle bouncing off a wall, with mid-frame position correction
    :param wall: the wall object that may intersect the particle
    :param particle: the particle in the vicinity of the wall
    :param dt: length of the timestep
    :return: Boolean value of true if a collision occured
    """
    x0 = particle.x
    u0 = particle.u
    x1 = wall.vert[0, :]
    p = x0 - x1
    r = particle.mole.radius

    unit = wall.unit
    norm = wall.norm
    dis = np.dot(p, norm)

    # Determine if a collision actually occured
    if dis > r:
        return False


    #if norm_dir > 0:
    #    return False

    # Decompose particles velocity normal and tangential to wall
    norm_dir = np.dot(u0, norm)
    nu = np.multiply(norm_dir, norm)
    uu = np.multiply(np.dot(u0, unit), unit)

    # Update velocity and position
    x0 -= u0 * dt
    dt0 = (np.abs(np.dot(x0 - x1, norm)) - r) / np.linalg.norm(nu)
    x0 += u0 * dt0
    particle.u = uu - nu
    particle.x = x0 + particle.u*(dt - dt0)

    return True