Example #1
0
void collision_resolve_hardsphere_withborder(struct collision c) {
    struct particle p1 = particles[c.p1];
    struct particle p2 = particles[c.p2];
    struct ghostbox gb = c.gb;
    double m21  = p1.m  /  p2.m;
    double x21  = p1.x + gb.shiftx  - p2.x;
    double y21  = p1.y + gb.shifty  - p2.y;
    double z21  = p1.z + gb.shiftz  - p2.z;
    double rp   = p1.r+p2.r;
    if (rp*rp < x21*x21 + y21*y21 + z21*z21) return;
    double vx21 = p1.vx + gb.shiftvx - p2.vx;
    double vy21 = p1.vy + gb.shiftvy - p2.vy;
    double vz21 = p1.vz + gb.shiftvz - p2.vz;
    if (vx21*x21 + vy21*y21 + vz21*z21 >0) return; // not approaching
    // Bring the to balls in the xy plane.
    // NOTE: this could probabely be an atan (which is faster than atan2)
    double theta = atan2(z21,y21);
    double stheta = sin(theta);
    double ctheta = cos(theta);
    double vy21n = ctheta * vy21 + stheta * vz21;
    double y21n = ctheta * y21 + stheta * z21;

    // Bring the two balls onto the positive x axis.
    double phi = atan2(y21n,x21);
    double cphi = cos(phi);
    double sphi = sin(phi);
    double vx21nn = cphi * vx21  + sphi * vy21n;

    // Coefficient of restitution
    double eps= coefficient_of_restitution_for_velocity(vx21nn);
    double dvx2 = -(1.0+eps)*vx21nn/(1.0+m21) ;
    if (dvx2<minimum_collision_velocity) {
        dvx2 = minimum_collision_velocity;
    }

    // Now we are rotating backwards
    double dvx2n = cphi * dvx2;
    double dvy2n = sphi * dvx2;
    double dvy2nn = ctheta * dvy2n;
    double dvz2nn = stheta * dvy2n;

    // Applying the changes to the particles.
    if (c.p2>N_border) {
        particles[c.p2].vx -=	m21*dvx2n;
        particles[c.p2].vy -=	m21*dvy2nn;
        particles[c.p2].vz -=	m21*dvz2nn;
        particles[c.p2].lastcollision = t;
    }
    if (c.p1>N_border) {
        particles[c.p1].vx +=	dvx2n;
        particles[c.p1].vy +=	dvy2nn;
        particles[c.p1].vz +=	dvz2nn;
        particles[c.p1].lastcollision = t;
    }
}
Example #2
0
// Function written by Akihiko Fujii
void collision_resolve_hardsphere_pullaway(struct collision c){
#ifndef COLLISIONS_NONE
	struct particle p1 = particles[c.p1];
	struct particle p2;
#ifdef MPI
	int isloc = communication_mpi_rootbox_is_local(c.ri);
	if (isloc==1){
#endif // MPI
		p2 = particles[c.p2];
#ifdef MPI
	}else{
		int root_n_per_node = root_n/mpi_num;
		int proc_id = c.ri/root_n_per_node;
		p2 = particles_recv[proc_id][c.p2];
	}
#endif // MPI
	//	if (p1.lastcollision==t || p2.lastcollision==t) return;
	struct ghostbox gb = c.gb;
	double x21  = p1.x + gb.shiftx  - p2.x; 
	double y21  = p1.y + gb.shifty  - p2.y; 
	double z21  = p1.z + gb.shiftz  - p2.z; 
	double r = sqrt(x21*x21 + y21*y21 + z21*z21);
	/* double r21 = sqrt(x21*x21 + y21*y21 + z21*z21); */
	double rp   = p1.r+p2.r;
	double oldvyouter;

	if (x21>0){
		oldvyouter = p1.vy;
	}else{
		oldvyouter = p2.vy;
	}

	if (rp*rp < x21*x21 + y21*y21 + z21*z21) return;

	double vx21 = p1.vx + gb.shiftvx - p2.vx; 
	double vy21 = p1.vy + gb.shiftvy - p2.vy; 
	double vz21 = p1.vz + gb.shiftvz - p2.vz; 

	if (vx21*x21 + vy21*y21 + vz21*z21 >0) return; // not approaching

	// Bring the to balls in the xy plane.
	// NOTE: this could probabely be an atan (which is faster than atan2) 
	double theta = atan2(z21,y21);
	double stheta = sin(theta);
	double ctheta = cos(theta);
	double vy21n = ctheta * vy21 + stheta * vz21;
	double y21n = ctheta * y21 + stheta * z21;

	// Bring the two balls onto the positive x axis.
	double phi = atan2(y21n,x21);
	double cphi = cos(phi);
	double sphi = sin(phi);
	double vx21nn = cphi * vx21  + sphi * vy21n;
	double vy21nn = -sphi* vx21  + cphi * vy21n;

	// Coefficient of restitution
	double eps= coefficient_of_restitution_for_velocity(vx21nn);
	double dvx2 = -(1.0+eps)*vx21nn;
	double dvy2 = (r/rp-1.)*vy21nn;

	double minr = (p1.r>p2.r)?p2.r:p1.r;
	double maxr = (p1.r<p2.r)?p2.r:p1.r;
	double mindv= minr*minimum_collision_velocity;
	mindv *= 1.-(r - maxr)/minr;
	if (mindv>maxr*minimum_collision_velocity)mindv = maxr*minimum_collision_velocity;
	if (dvx2<mindv) dvx2 = mindv;

	// added
	double dxx2 = rp-r;
	double dxx2n = cphi * dxx2;
	double dxy2n = sphi * dxx2;
	double dxy2nn = ctheta * dxy2n;
	double dxz2nn = stheta * dxy2n;

	// Now we are rotating backwards
	/* double dvx2n = cphi * dvx2;	 */
	/* double dvy2n = sphi * dvx2; */

	// updated
	double dvx2n = cphi * dvx2 - sphi * dvy2;
	double dvy2n = sphi * dvx2 + cphi * dvy2;

	double dvy2nn = ctheta * dvy2n;
	double dvz2nn = stheta * dvy2n;

	// Applying the changes to the particles.
#ifdef MPI
	if (isloc==1){
#endif // MPI

		const double p1pf = p1.m/(p1.m+p2.m);
		const double p2pf = p2.m/(p1.m+p2.m);
		particles[c.p2].vx -=	p1pf*dvx2n;
		particles[c.p2].vy -=	p1pf*dvy2nn;
		particles[c.p2].vz -=	p1pf*dvz2nn;
		particles[c.p2].lastcollision = t;

		// added
		particles[c.p2].x -=	p1pf*dxx2n;
		particles[c.p2].y -=	p1pf*dxy2nn;
		particles[c.p2].z -=	p1pf*dxz2nn;
#ifdef MPI
	}
#endif // MPI
	particles[c.p1].vx +=	p2pf*dvx2n;
	particles[c.p1].vy +=	p2pf*dvy2nn;
	particles[c.p1].vz +=	p2pf*dvz2nn;

	// added
	particles[c.p1].x +=	p2pf*dxx2n; 
	particles[c.p1].y +=	p2pf*dxy2nn; 
	particles[c.p1].z +=	p2pf*dxz2nn; 

	particles[c.p1].lastcollision = t;

#endif // COLLISIONS_NONE
}