int random_partition(int a[], int start, int end)
{
    int ran = random_2(start, end);
    std::swap(a[ran], a[end]);

    int pivot = a[end];
    int i = start - 1;
    for (int j = start; j < end; j++)
        if (a[j] <= pivot)
            std::swap(a[j], a[++i]);
    std::swap(a[++i], a[end]);
    return i;
}
Exemple #2
0
void track_through_matter(
                          double **part, long np, MATTER *matter, double Po
                          )
{
  long ip;
  double L, Nrad, *coord, theta_rms, beta, P, gamma=0.0;
  double z1, z2, dx, dy, ds, t=0.0, dGammaFactor;
  double K1, K2=0.0, sigmaTotal, probScatter=0.0, dgamma;
  long nScatters=0;
  
  log_entry("track_through_matter");

  if (particleIsElectron==0)
    bombElegant("MATTER element doesn't work for particles other than electrons", NULL);
  
  if ((L=matter->length)==0)
    return;

  beta = Po/sqrt(sqr(Po)+1);
  if (matter->Xo==0)
    Nrad = theta_rms = 0;
  else {
    Nrad = matter->length/matter->Xo;
    theta_rms = 13.6/particleMassMV/Po/sqr(beta)*sqrt(Nrad)*(1+0.038*log(Nrad));
  }
  dGammaFactor = 1-exp(-Nrad);
  
  if (Nrad<1e-3) {
    if (matter->Z<1 || matter->A<1 || matter->rho<=0)
      bombElegant("MATTER element is too thin---provide Z, A, and rho for single-scattering calculation.", NULL);
    K1 = 4*sqr(matter->Z*particleRadius/(beta*Po));
    K2 = sqr(pow(matter->Z, 1./3.)/137.036/Po);
    sigmaTotal = K1*pow(PI, 3)/(sqr(K2)+K2*SQR_PI);
    probScatter = matter->rho/(AMU*matter->A)*matter->length*sigmaTotal;
    /* fprintf(stdout, "K1=%le, K2=%le, mean expected number of scatters is %le\n", K1, K2, probScatter); */
  }
  
  for (ip=0; ip<np; ip++) {
    coord = part[ip];
    if (Nrad) {
      if (!matter->elastic) {
        P = (1+coord[5])*Po;
        gamma = sqrt(sqr(P)+1);
        beta = P/gamma;
        t = coord[4]/beta;
      }
      if (Nrad>=1e-3) {
        /* multiple scattering */
        z1 = gauss_rn(0, random_2);
        z2 = gauss_rn(0, random_2);
        coord[0] += (dx=(z1/SQRT_3 + z2)*L*theta_rms/2 + L*coord[1]);
        coord[1] += z2*theta_rms;
        z1 = gauss_rn(0, random_2);
        z2 = gauss_rn(0, random_2);
        coord[2] += (dy=(z1/SQRT_3 + z2)*L*theta_rms/2 + L*coord[3]);
        coord[3] += z2*theta_rms;
        ds = sqrt(sqr(L)+sqr(dx)+sqr(dy));
      }
      else {
        long sections;
        double F, theta, phi, zs, dxp, dyp, L1, prob;
        
        sections = probScatter/matter->pLimit+1;
        L1 = L/sections;
        prob = probScatter/sections;
        ds = 0;
        while (sections-- > 0) {
          if (random_2(1)<prob) {
            nScatters ++;
            /* single-scattering computation */
            /* scatter occurs at location 0<=zs<=L */
            zs = L1*random_2(1);
            /* pick a value for CDF and get corresponding angle */
            F = random_2(1);
            theta = sqrt((1-F)*K2*SQR_PI/(K2+F*SQR_PI));
            phi = random_2(1)*PIx2;
            dxp = theta*sin(phi);
            dyp = theta*cos(phi);
            /* advance to location of scattering event */
            ds += zs*sqrt(1+sqr(coord[1])+sqr(coord[3]));
            /* scatter */
            coord[1] += dxp;
            coord[3] += dyp;
            /* advance to end of slice */
            coord[0] += dxp*(L1-zs);
            coord[2] += dyp*(L1-zs);
            ds += (L1-zs)*sqrt(1+sqr(coord[1])+sqr(coord[3]));
          } else {
            ds += L1*sqrt(1+sqr(coord[1])+sqr(coord[3]));
            coord[0] += coord[1]*L1;
            coord[2] += coord[3]*L1;
          }            
        }
      }
      if (!matter->elastic) {
        dgamma = gamma*dGammaFactor;
        if (matter->energyStraggle) {
          double dgamma1;
          /* very simple-minded estimate: StDev(dE) = Mean(dE)/2 */
          while ((dgamma1 = dgamma*(1+0.5*gauss_rn(0, random_2)))<0)
            ;
          dgamma = dgamma1;
        }
        gamma -= dgamma;
        P = sqrt(sqr(gamma)-1);
        coord[5] = (P-Po)/Po;
        beta = P/gamma;
        coord[4] = t*beta+ds;
      }
      else
        coord[4] += ds;
    }
    else {
      coord[0] += L*coord[1];
      coord[2] += L*coord[3];
      coord[4] += L*sqrt(1+sqr(coord[1])+sqr(coord[3]));
    }
  }
/*
  if (Nrad<1e-3)
    fprintf(stdout, "%e scatters per particle\n",
            (1.0*nScatters)/np);
*/
  
  log_exit("track_through_matter");
}
Exemple #3
0
/* Launches one of those fancy effects. */
void launch_effect(int effect)
{
    switch (effect) {
    case 0:
	/* Lights all the layers one by one. */
	load_bar(1000);
	break;
    case 1:
	/* A pixel bouncing randomly around. */
	boing_boing(150, 500, 0x03, 0x01);
	break;
    case 2:
	/* Randomly fill and empty the cube. */
	fill(0x00);
	random_filler(100, 1, 500, 1);
	random_filler(100, 1, 500, 0);
	break;
    case 3:
	/* Send voxels randomly back and forth the z-axis. */
	send_voxels_rand_z(150, 500, 2000);
	break;
    case 4:
	/* Spinning spiral */
	spiral(1, 75, 1000);
	break;
    case 5:
	/* A coordinate bounces randomly around the cube. For every position
	 * the status of that voxel is toggled. */
	boing_boing(150, 500, 0x03, 0x02);
	break;
    case 6:
	/* Random raindrops */
	rain(40, 1000, 500, 500);
	break;
		
    case 7:
	/* Snake: a snake randomly bounce around the cube. */
	boing_boing(150, 500, 0x03, 0x03);
	break;
    case 8:
	/* Spinning plane */
	spinning_plane(1, 50, 1000);
	break;
    case 9:
	/* Set x number of random voxels, delay, unset them. x increases
	 * from 1 to 32 and back to 1. */
	random_2(48);
	break;
    case 10:
	/* Set then unset all 64 voxels in a random order. */
	random_filler2(200, 1);
	delay_ms(2000);
	random_filler2(200, 0);
	delay_ms(1000);
	break;
    case 11:
	/* Bounce a plane up and down all the directions. */
	fly_plane('z', 1, 1000);
	delay_ms(2000);
	fly_plane('y', 1, 1000);
	delay_ms(2000);
	fly_plane('x', 1, 1000);
	delay_ms(2000);
	fly_plane('z', 0, 1000);
	delay_ms(2000);
	fly_plane('y', 0, 1000);
	delay_ms(2000);
	fly_plane('x', 0, 1000);
	delay_ms(2000);
	break;
    case 12:
	/* Fade in and out at low framerate. */
	blinky2();
	break;
    case 13:
	/* Random walk */
	random_walk(4, 250, 1000);
	break;
    case 14:
	/* Spinning square */
	spinning_square(1, 50, 1000);
	break;
    }
}