Beispiel #1
0
// constructor sets up new sphere
// NOTE : while condition was removed
// TODO : maybe include it again
Sphere::Sphere(double rad)
{
	// RADIUS MUST BE BEFORE RANDOM POINTS
	radius = rad;
	// gets 4 random points for the bezier curve
	p1 = random_ranged_point(radius);
	p2 = new_curve_point(p1);		
	p3 = new_curve_point(p2);
	p4 = new_curve_point(p3);
	
	// position starts at p1
	pos = p1;
	// 3D
	previous_pos.x = 0.0;
	previous_pos.y = 5.0;
	previous_pos.z = 0.0;
	// = {0.0, 5.0, 0.0};
		
	// gets a random direction, this might be a wasted step
	direction = random_direction(radius);

	active = 0;
	velocity = random_velocity();	

	// start on a curved path
	path = 1;
	color = random_color();		

	curve_length = get_curve_length();
	start_time = (double) clock();
	curve_time = curve_length / velocity;
	ghost = 0;
}
void satellite(Halo const * const h, Particle* const g)
{
#ifdef DEBUG
  assert(random_generator);
  assert(solver);
#endif
  
  const double a= 1.0/(1.0 + h->z);
  const double rho_m= cosmology_rho_m()/(a*a*a); // physical [1/h Mpc]^-3
  const double r200m= 1000.0*pow(h->M/(4.0*M_PI/3.0*200.0*rho_m), 1.0/3.0);
    // physical 1/h kpc
  const double c200m= r200m/h->rs;

  //fprintf(stderr, "r200m c rs %e %e %e\n", r200m, c200m, h->rs);

  // draw random mass M(r)/M0 between [0, f(c200m)]
  const double fmax= f(c200m);
  const double fx= fmax*gsl_rng_uniform(random_generator);

  // solve for f(x) = fx, where x= r/r_s
  double x= c200m*fx/fmax; // initial guess

  x= f_inverse(fx, x);

  double r_sat= x*h->rs; // location of the satellite from center
  
  // compute vrms(r)
  double vrms= compute_v_rms(r_sat, h->M, r200m, c200m);

  r_sat= r_sat/(1000.0f*a); // physical /h kpc -> comoving /h Mpc

  float e[3];
  random_direction(e);

  // satellite x v contains only offset from halo
  
  g->x[0] = r_sat*e[0];
  g->x[1] = r_sat*e[1];
  g->x[2] = r_sat*e[2];

  g->vr= vrms*gsl_ran_ugaussian(random_generator);
}
Beispiel #3
0
  void SliceSampler::initialize(){
    random_direction();
    pstar = f(theta);
    if(!std::isfinite(pstar)){
      std::string msg = "invalid condition used to initialize SliceSampler";
      throw_exception<std::runtime_error>(msg);
    }

    plo = f(theta-lo*z);
    while(!std::isfinite(plo)){
      lo/=2.0;
      plo = f(theta-lo*z);
    }

    phi = f(theta+hi*z);
    while(!std::isfinite(phi)){
      hi/=2.0;
      phi = f(theta+hi*z);
    }
  }
static void deal_automatic_tank_motion(object_type_t *tank,tank_battle_t *tank_battle,BOOL random)
{
	object_type_t *tk=tank;
	tank_battle_t *tb=tank_battle;
	dir_t dir=DIR_NONE;
	BOOL flag_change_dir=FALSE;
	BOOL flag_rotate=FALSE;
	BOOL flag_fire=FALSE;
	
	flag_change_dir=is_change_direction(TANK_MODEL_NUM);
	if((TRUE==flag_change_dir)||(random==FALSE)){
		dir=random_direction();
		flag_rotate=can_rotate_direction(dir,tk,tb);
		if(TRUE==flag_rotate){
			rotate_direction(dir,tk);
		}
	}
	flag_fire=is_fire(tb->speed);
	if(TRUE==flag_fire){
		fire(tk,tb->bullet);
	}
}
/*
 * struct sphere generate_sphere();
 * 
 * return a ball 
 */
struct sphere generate_sphere() {
		struct sphere ball;
		
		do{
			// RADIUS MUST BE BEFORE RANDOM POINTS
			ball.radius = random_radius();
			// gets 4 random points for the bezier curve
			ball.p1 = random_ranged_point(ball.radius);
			ball.p2 = new_curve_point(ball.p1);		
			ball.p3 = new_curve_point(ball.p2);
			ball.p4 = new_curve_point(ball.p3);
			
			// position starts at p1
			ball.pos = ball.p1;
			ball.previous_pos = {0.0, 0.0};
	//printf("generation: %f %f || %f %f\n", ball.previous_pos.x, ball.previous_pos.y, ball.pos.x, ball.pos.y);
			
			// gets a random direction, this might be a wasted step
			ball.direction = random_direction(ball.radius);

			ball.active = 0;

			ball.velocity = random_velocity();	

			// start on a curved path
			ball.path = 1;
			// dead variable is set to 0, used to prevent collisions
			//ball.dead = 0;
			ball.color = random_color();		

			ball.curve_length = curve_length( &ball );
			ball.start_time = (double) clock();
			ball.curve_time = ball.curve_length / ball.velocity;
			ball.ghost = 0;
		}while(collision_detection(ball) == 1 );	
		
		return ball;
}
/*
 * struct sphere generate_sphere();
 * 
 * return a ball 
 */
struct sphere generate_sphere(int rad) {
		struct sphere ball;
		
		do{
			// RADIUS MUST BE BEFORE RANDOM POINTS
			ball.radius = (rad) ? next_ball_radius : random_radius();
			// gets 4 random points for the bezier curve
			ball.p1 = random_ranged_point(ball.radius);
			ball.p2 = new_curve_point(ball.p1);		
			ball.p3 = new_curve_point(ball.p2);
			ball.p4 = new_curve_point(ball.p3);
			
			// position starts at p1
			ball.pos = ball.p1;
			// 3D
			ball.previous_pos = {0.0, 5.0, 0.0};
			
			// gets a random direction, this might be a wasted step
			ball.direction = random_direction(ball.radius);

			ball.active = 0;

			ball.velocity = random_velocity();	

			// start on a curved path
			ball.path = 1;
			ball.color = random_color();		

			ball.curve_length = curve_length( &ball );
			ball.start_time = (double) clock();
			ball.curve_time = ball.curve_length / ball.velocity;
			ball.ghost = 0;
			// 3D
		}while(collision_detection(ball) == 1 || ball.p1.x == 0.0 || ball.p1.y == 0.0 ||
				ball.p1.z == 0.0);	
		
		return ball;
}
Beispiel #7
0
int main()
{
    std::vector<char> board(100, Empty);

    pos_t pos    = 0;
    char station = 'A';
    board[pos]   = station++;

    // generate moves
    std::deque<move> history {}; // start with an empty move
    move pending {};

    auto select = [&] () -> bool
    { 
        auto& taken = pending.taken;
        auto& tried = pending.tried;

        pos_t nw;

        do
        {
            // random untried direction
            do    taken        = random_direction();
            while (end(tried) != tried.find(taken));

            // calculate new position
            nw = pos + taken;

            // validate new position
            bool valid = 
                (nw>=0) && (nw<(int)board.size()) && // within bounds?
                board[nw]==Empty &&                  // unvisited?
                // detect moving across the edge using invariant: 
                // INV: only col/row allowed to change
                (!(pos%10 - nw%10) != !(pos/10 - nw/10));

            // mark tried
            tried.insert(taken);

            // return if valid/no candidates
            if (valid || 4 == tried.size())
                return valid;

        } while (true); // try another direction
    };

    auto display = [&] {
        for(auto row = begin(board); row<end(board); row+=10)
            std::cout << std::string(row, row+10) << "\n";
    };

    auto apply = [&] () mutable {
        std::cout << pending.taken;

        pos        += pending.taken;
        board[pos]  = station++;

        history.emplace_back();
        std::swap(pending, history.back());
        //display();
    };

    auto backtrack = [&] () mutable {
        std::swap(pending, history.back());
        history.pop_back();
        std::cout << "[-" << pending.taken << "]";

        board[pos]  = (--station, Empty);
        pos        -= pending.taken;
        //display();
    };

    // game loop
    std::cout << "\nGenerating: ";

    while (station<='Z')
        select()? apply() : backtrack();

    std::cout << "\nResulting board: \n";

    display();
}
Beispiel #8
0
void inky::update(level l, pacman p, blinky b, int stage){
    //std::cout << "here's pnky's update" << std::endl;
    if (vulnerable){
        vulnerable_method();
    } else {
        sprite.setColor(col);
    }
    if (jailed && can_leave && !vuln_in_jail && gate_clock.getElapsedTime().asSeconds() > 1){
        //std::cout << "jailed" << std::endl;
        leave_jail();
    } else if (!jailed){
        //x or y priority to prevent infinite turning/bounce loops
        int dir_priority = 0;
        if (std::abs(ypos - goal_y) > std::abs(xpos - goal_x)){
            dir_priority = 1;
        }

        if (stage == 0 || stage == 2 || stage == 4 || stage == 6){
            //std::cout << "scatter! pinky!" << std::endl;
            bool sel = false;
            if (search_for_intersection(l) && turn_timer.getElapsedTime().asMilliseconds() > 500){
                //std::cout << "found an intersection" << std::endl;
                dirs = find_options(l);
                //for (unsigned i = 0; i < dirs.size(); i++){
                //    std::cout << dirs.at(i) << std::endl;
                //}

                //x priority
                if (dir_priority == 0){
                    if (xpos <= home_x && !sel && dir != 3){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 2){
                                //std::cout << "selecting dir 2" << std::endl;
                                select_direction(2);
                                sel = true;
                            }
                        }
                    }

                    if (ypos <= home_y && !sel && dir != 0){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 1){
                                //std::cout << "selecting dir 1" << std::endl;
                                select_direction(1);
                                sel = true;
                            }
                        }
                    }

                    if (!sel){
                        select_direction(random_direction(dirs));
                    }
                }

                //y priority
                if (dir_priority == 1){
                    if (ypos <= home_y && !sel && dir != 0){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 1){
                                //std::cout << "selecting dir 1" << std::endl;
                                select_direction(1);
                                sel = true;
                            }
                        }
                    }

                    if (xpos <= home_x && !sel && dir != 3){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 2){
                                //std::cout << "selecting dir 2" << std::endl;
                                select_direction(2);
                                sel = true;
                            }
                        }
                    }
                }

                if (!sel){
                    select_direction(random_direction(dirs));
                }
            }

//            if (stage == 4 || stage == 6){
//                if (chase_pacman.getElapsedTime().asSeconds() >= 5){
//                    stage++;
//                    scatter.restart();
//                }
//            } else {
//                if (chase_pacman.getElapsedTime().asSeconds() >= 7){
//                    stage++;
//                    scatter.restart();
//                }
//            }
        }
        //chasing pacman
        else {
            //std::cout << "chase! pinky!" << std::endl;

            if (vulnerable){
                goal_x = home_x;
                goal_y = home_y;
            } else {
                if (p.get_dir() == 0){
                    goal_x = p.get_xpos() - 50;
                    goal_y = p.get_ypos() - 50;
                    goal_x = goal_x + (goal_x - b.get_xpos());
                    goal_y = goal_y + (goal_y - b.get_ypos());
                    if (goal_x < 25){
                        goal_x = 25;
                    }
                    if (goal_y < 25){
                        goal_y = 25;
                    }
                }
                else if (p.get_dir() == 1){
                    goal_x = p.get_xpos();
                    goal_y = p.get_ypos() + 50;
                    goal_x = goal_x + (goal_x - b.get_xpos());
                    goal_y = goal_y + (goal_y - b.get_ypos());
                    if (goal_y > 650){
                        goal_y = 650;
                    }
                }
                else if (p.get_dir() == 2){
                    goal_x = p.get_xpos() + 50;
                    goal_y = p.get_ypos();
                    goal_x = goal_x + (goal_x - b.get_xpos());
                    goal_y = goal_y + (goal_y - b.get_ypos());
                    if (goal_x > 500){
                        goal_x = 500;
                    }
                } else {
                    goal_x = p.get_xpos() - 50;
                    goal_y = p.get_ypos();
                    goal_x = goal_x + (goal_x - b.get_xpos());
                    goal_y = goal_y + (goal_y - b.get_ypos());
                    if (goal_x < 25){
                        goal_x = 25;
                    }
                }
            }



            bool sel = false;
            if (search_for_intersection(l) && turn_timer.getElapsedTime().asMilliseconds() > 500){
                //std::cout << "found an intersection" << std::endl;
                dirs = find_options(l);
                //for (unsigned i = 0; i < dirs.size(); i++){
                    //std::cout << dirs.at(i) << std::endl;
                //}

                if (dir_priority == 0){
                    if (xpos >= goal_x && !sel && dir != 2){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 3){
                                //std::cout << "selecting dir 3" << std::endl;
                                select_direction(3);
                                sel = true;
                            }
                        }
                    }

                    else if (xpos < goal_x && !sel && dir != 3) {
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 2){
                                //std::cout << "selecting dir 2" << std::endl;
                                select_direction(2);
                                sel = true;
                            }
                        }
                    }

                    if (ypos >= goal_y && !sel && dir != 1){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 0){
                                //std::cout << "selecting dir 0" << std::endl;
                                select_direction(0);
                                sel = true;
                            }
                        }
                    }

                    else if (ypos < goal_y && !sel && dir != 0){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 1){
                                //std::cout << "selecting dir 1" << std::endl;
                                select_direction(1);
                                sel = true;
                            }
                        }
                    }
                }

                if (dir_priority == 1){
                    if (ypos >= goal_y && !sel && dir != 1){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 0){
                                //std::cout << "selecting dir 0" << std::endl;
                                select_direction(0);
                                sel = true;
                            }
                        }
                    }

                    else if (ypos < goal_y && !sel && dir != 0){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 1){
                                //std::cout << "selecting dir 1" << std::endl;
                                select_direction(1);
                                sel = true;
                            }
                        }
                    }

                    if (xpos >= goal_x && !sel && dir != 2){
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 3){
                                //std::cout << "selecting dir 3" << std::endl;
                                select_direction(3);
                                sel = true;
                            }
                        }
                    }

                    else if (xpos < goal_x && !sel && dir != 3) {
                        for (unsigned i = 0; i < dirs.size(); i++){
                            if (dirs.at(i) == 2){
                                //std::cout << "selecting dir 2" << std::endl;
                                select_direction(2);
                                sel = true;
                            }
                        }
                    }
                }

                if (!sel){
                    select_direction(random_direction(dirs));
                }
            }


//            if (stage == 1 || stage == 3 || stage == 5){
//                if (scatter.getElapsedTime().asSeconds() >= 20){
//                    stage++;
//                    chase_pacman.restart();
//                }
//            }
        }

    }

    update_position(l);
}
Beispiel #9
0
void sidm(void)
{
  int     i,ii,j,k,n, numngb;
  double  h, hinv, hinv3, r, u, wk=0.0;      
  float   *r2list;
  int     *ngblist;
  double  tstart,tend;
  int     ntot,ntotleft,npleft,nthis;     
  int     nstart,nbuffer,ncount,nchunk;
  int     timelinecounter,startcounter;  
  int     *nrecv,*noffset;
  int     level,sendTask,recvTask;
  int     place, nexport;
  int     num_collisionless;
  MPI_Status status;
  
  double  dt_h0;
  double  rand, C_Pmax, P_max, Prob;
  double  rv, rvx, rvy, rvz;
  double  rmass;
  double  nx[3];
  double  dvx, dvy, dvz;
  double  s_a, s_a_inverse;
  double  CrossSectionCo;
  int    nscat[3], nscatTot[3]; 

#if (CROSS_SECTION_TYPE == 2)
  double beta, v_dep;
#elif (CROSS_SECTION_TYPE == 3)
  double n_cross_section; // sigma = sigma0*(dv/v_scale)^n
  double v_scale;
#elif (CROSS_SECTION_TYPE == 4)
  double beta, cosO, sin22, sinO, denom;
  double rvv[3], nperp[3];
#endif

  
  
  /* file for scattering log */
#ifdef SCATTERLOG
  FILE   *fp;
  char   filename[128];
  struct scatlog ScatLog;
  ScatLog.time= All.Time;
  sprintf(filename, "sct_%03d.%d", All.SnapshotFileCount, ThisTask);
  //sprintf(filename, "sct.%d", ThisTask);
  fp = fopen(filename, "ab");
#endif

  for(k=0; k<3; k++)
    nscat[k]= nscatTot[k]= 0;
    
  num_collisionless= NumForceUpdate-NumSphUpdate;

  MPI_Allreduce(&num_collisionless, &ntot, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

  /* compute maximum size of bunch that may come from this task */
  if(num_collisionless==0)
    nthis=1;
  else
    nthis = ((double)(num_collisionless)*(All.BunchSizeSidm-NTask))/ntot + 1; 


  if(num_collisionless>0) {
    nchunk= num_collisionless/nthis; /* number of bunches needed */  
    if((num_collisionless % nthis)>0) nchunk+=1;
  }
  else
    nchunk= 0;


  nrecv= malloc(sizeof(int)*NTask);  /* list of particle numbers that constituate current bunch */
  noffset= malloc(sizeof(int)*NTask);  /* offsets of bunches in common list */

  ntotleft= ntot;              /* particles left for all tasks together */
  npleft= num_collisionless;   /* particles left for this task */

  nstart= IndFirstUpdate;      /* first particle for this task */
  startcounter=0;

  while(ntotleft > 0){
    if(nthis > npleft)
      nthis= npleft;

    for(i=nstart, ncount=0, nexport=0, timelinecounter=startcounter; 
        timelinecounter<NumForceUpdate && ncount<nthis; 
        i=P[i].ForceFlag, timelinecounter++) {
      if(P[i].Type>0) {
        ncount++;
        
        for(j=0; j<3; j++) {
          if(P[i].PosPred[j] < (DomainMin[P[i].Type][j] + P[i].HsmlVelDisp))
            break;
          if(P[i].PosPred[j] > (DomainMax[P[i].Type][j] - P[i].HsmlVelDisp))
            break;
        }
        
        if(j != 3) {
	  /* particle lies NOT completely inside. 
	     needs to be sent to other processors */
          nexport++;
          P[i].Type |= 8;
        }
      }
    }

    MPI_Allgather(&nexport, 1, MPI_INT, nrecv, 1, MPI_INT, MPI_COMM_WORLD);
    MPI_Allreduce(&ncount, &ntot, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
      
    for(i=nbuffer=0; i<NTask; i++)  /* compute length of common list */
      nbuffer += nrecv[i];
      
    for(i=1, noffset[0]=0; i<NTask; i++) /* set-up offset-table */
      noffset[i]= noffset[i-1] + nrecv[i-1];

    /* fill in the own particles at the right place */
    for(i=nstart, ncount=0, nexport=0, timelinecounter=startcounter; 
        timelinecounter < NumForceUpdate && ncount < nthis; 
        i=P[i].ForceFlag, timelinecounter++) {
      if(P[i].Type > 0) {
        if(P[i].Type & 8) {
          place= noffset[ThisTask] + nexport; 
          nexport++;
        }
        else
          place= nbuffer + (ncount-nexport);
        
        for(k=0; k<3; k++) {
          SidmDataIn[place].Pos[k]= P[i].PosPred[k];
          SidmDataIn[place].Vel[k]= P[i].Vel[k];
        }
        SidmDataIn[place].Hsml= P[i].HsmlVelDisp;
        SidmDataIn[place].Type= P[i].Type & 7;
        SidmDataIn[place].Mass= P[i].Mass;
	if(P[i].dVel[0] != 0.0f)
	  SidmDataIn[place].ID= 0; // Oct 9, 2005
	else
	  SidmDataIn[place].ID= P[i].ID;
        SidmDataIn[place].dt= 2*(All.Time - P[i].CurrentTime);
        
        SidmDataConfirm[place].Task= -1;
        ncount++;
      }
    }

    /* 1st big communication */
    tstart= second();      
    for(level=1; level<NTask; level++) {
      sendTask = ThisTask;
      recvTask = ThisTask ^ level; 
      
      MPI_Sendrecv(&SidmDataIn[noffset[sendTask]], 
		   nrecv[sendTask]*sizeof(struct sidmdata_in), 
		   MPI_BYTE, recvTask, TAG_ANY, 
                   &SidmDataIn[noffset[recvTask]], 
		   nrecv[recvTask]*sizeof(struct sidmdata_in), MPI_BYTE, 
		   recvTask, TAG_ANY, MPI_COMM_WORLD, &status);
    }
    tend=second();
    All.CPU_CommSum += timediff(tstart, tend);

    /* ok, all preparations are done. */
    /* SIDM: MAIN PART */

    /* Common Factors */
    /* s_a= a^{3/2} H
       ==> s_a_inverse da = a^{-1/2} dt
       ==> s_a_inverse da v_internal= a^{-1} v_phys dt = dx_comoving  
    */
    if(All.ComovingIntegrationOn) {
      s_a= All.Hubble*sqrt(All.Omega0 + All.Time*
           (1-All.Omega0-All.OmegaLambda)+pow(All.Time,3)*All.OmegaLambda);
      s_a_inverse= 1/s_a;
#if (CROSS_SECTION_TYPE == 0)
      CrossSectionCo = All.CrossSectionInternal/pow(All.Time,2);  
      C_Pmax= SAFEFACTOR * 
              BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*2*vmax*
	      CrossSectionCo;
#elif (CROSS_SECTION_TYPE == 1)
      CrossSectionCo = All.CrossSectionInternal/pow(All.Time,2.5);
      // a^(1/2) factor considers that in s_a_inverse
      C_Pmax= SAFEFACTOR * 
              BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*
              CrossSectionCo;
#elif (CROSS_SECTION_TYPE == 2)
      CrossSectionCo = All.CrossSectionInternal/pow(All.Time,2);  
      vc= All.YukawaVelocity/sqrt(All.Time); /* In internal unit */
      if(2.0*vmax < vc/sqrt(3.0)) {
	beta= 2.0*vmax/vc;
	v_dep= 1.0/(1.0 + beta*beta);
	C_Pmax= SAFEFACTOR * 
	        BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*
	        2.0*vmax*v_dep*v_dep*
                CrossSectionCo;
      }
      else {
	C_Pmax= SAFEFACTOR * 
                BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*
	        (3.0*sqrt(3.0)/16.0)*vc*
                CrossSectionCo;
      }
#elif (CROSS_SECTION_TYPE == 3)
      CrossSectionCo = All.CrossSectionInternal/pow(All.Time, 2);
      n_cross_section= All.CrossSectionPowLaw;
      v_scale= All.CrossSectionVelScale;
      C_Pmax= SAFEFACTOR * 
	      BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*2*v_scale*
	      CrossSectionCo;
#elif (CROSS_SECTION_TYPE == 4)
      vc= All.YukawaVelocity/sqrt(All.Time);
      CrossSectionCo = All.CrossSectionInternal/pow(All.Time,2);  
      C_Pmax= SAFEFACTOR * 
              BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*2*vmax*
	      CrossSectionCo;

#endif
    }

    else{
      s_a_inverse= 1.0;
#if (CROSS_SECTION_TYPE == 0)
      C_Pmax= SAFEFACTOR * 
	      BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*2*vmax*
              All.CrossSectionInternal;
#elif (CROSS_SECTION_TYPE == 1)
      C_Pmax= SAFEFACTOR * 
	      BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*
              All.CrossSectionInternal;
#elif (CROSS_SECTION_TYPE == 2)
      vc= All.YukawaVelocity;
      if(2.0*vmax < vc/sqrt(3.0)) {
	beta= 2.0*vmax/vc;
	v_dep= 1.0/(1.0 + beta*beta);
	C_Pmax= SAFEFACTOR * 
	        BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*
	        2.0*vmax*v_dep*v_dep*
	        All.CrossSectionInternal;
      }
      else {
	C_Pmax= SAFEFACTOR * 
                BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*
                (3.0*sqrt(3.0)/16.0)*vc*
	        All.CrossSectionInternal;
      }
#elif (CROSS_SECTION_TYPE == 3)
      n_cross_section= All.CrossSectionPowLaw;
      v_scale= All.CrossSectionVelScale;

      C_Pmax= SAFEFACTOR * 
	      BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*2*v_scale*
              All.CrossSectionInternal;
#elif (CROSS_SECTION_TYPE == 4)
      vc= All.YukawaVelocity;
      C_Pmax= SAFEFACTOR * 
	      BALLINVERSE*(All.DesNumNgb+All.MaxNumNgbDeviation)*2*vmax*
              All.CrossSectionInternal;

#endif
      CrossSectionCo = All.CrossSectionInternal;
    }

    /* For each active particles */
    for(i=0; i<(nbuffer+ncount-nexport); i++) {
      numngb= ngb_treefind_variable(&SidmDataIn[i].Pos[0], 
                    SidmDataIn[i].Hsml, 
                    SidmDataIn[i].Type, 
                    &ngblist, &r2list);   
      SidmDataResult[i].Ngb= numngb;

      dt_h0= SidmDataIn[i].dt * s_a_inverse;

      h     = SCATKERNELFACTOR * SidmDataIn[i].Hsml; // Oct 31, 2005
      hinv  = 1.0/h;
      hinv3 = hinv*hinv*hinv;
      
      /* Initialize Variables */
      SidmDataResult[i].dv[0] = 0.0;
      SidmDataResult[i].dv[1] = 0.0;
      SidmDataResult[i].dv[2] = 0.0;
      SidmTarget[i] = 0; /* for security */

      P_max = C_Pmax*SidmDataIn[i].Mass*hinv3*dt_h0;
      // This P_max is not correct if Masses are different. 

      rand = ran2(&iseed);
      
      if(P_max < rand)
        continue;
      else if(SidmDataIn[i].ID == 0)
	continue; // Already Scattered

      nscat[0]++; /* Passed first approximation */
      
      Prob= 0.0;
      /* for each neighbors */
      for(n=0; n<numngb; n++) {
        j  = ngblist[n]+1; 
        r  = sqrt(r2list[n]); /* There was a BUG! */

	if(P[j].dVel[0] != 0.0f)
	  continue; // No double scattering. Oct 9, 2005
        
        if(r < h) {
          u = r*hinv;
          ii = (int)(u*KERNEL_TABLE);
          wk =hinv3*( Kernel[ii]  + (Kernel[ii+1]-Kernel[ii])*(u-KernelRad[ii])*KERNEL_TABLE);
        }
	
        /* Relative Velocities */
        rvx = SidmDataIn[i].Vel[0] - P[j].Vel[0];
        rvy = SidmDataIn[i].Vel[1] - P[j].Vel[1];
        rvz = SidmDataIn[i].Vel[2] - P[j].Vel[2];
        rv  = sqrt(rvx*rvx + rvy*rvy + rvz*rvz);

#if (CROSS_SECTION_TYPE == 0)
        Prob += 0.5*P[j].Mass*wk*rv*CrossSectionCo*dt_h0;
#elif (CROSS_SECTION_TYPE == 1)
        Prob += 0.5*P[j].Mass*wk*   CrossSectionCo*dt_h0;
#elif (CROSS_SECTION_TYPE == 2)
	beta= rv/vc;
	v_dep= 1.0/(1.0+beta*beta);
	Prob += 0.5*P[j].Mass*wk*rv*v_dep*v_dep*CrossSectionCo*dt_h0;
#elif (CROSS_SECTION_TYPE == 3)
        Prob += 0.5*P[j].Mass*wk*rv*pow(rv/v_scale, n_cross_section)*CrossSectionCo*dt_h0;
#elif (CROSS_SECTION_TYPE == 4)
        Prob += 0.5*P[j].Mass*wk*rv*CrossSectionCo*dt_h0;
#endif

        if(Prob < rand)
          continue;

	SidmTarget[i] = j;        
        rmass = P[j].Mass / (SidmDataIn[i].Mass + P[j].Mass);

#if (CROSS_SECTION_TYPE == 4)
	// Furture selection of angle
	beta= rv/vc;
	rand = ran2(&iseed);
	cosO = 2.0*ran2(&iseed) - 1.0;    // cos(theta) of scatter direction
	sin22 = 0.5*(1.0 - cosO);         // sin^2(theta/2)
	denom = 1.0 + beta*beta*sin22;
	if(rand >= 1/(denom*denom) || rv == 0.0)
	  continue;

	if(rv == 0.0) { // debug
	  //printf("Error: rv == 0. %e %e\n", rv, 0.5*P[j].Mass*wk*rv*CrossSectionCo*dt_h0);
	  endrun(4006);
	}

	rvv[0]= rvx; rvv[1]= rvy; rvv[2]= rvz;
	random_direction(nx);


	perp(rvv, nx, nperp);

	//if(nperp[0] != nperp[0] || nperp[1] != nperp[1] || nperp[2] != nperp[2])
	//  endrun(4002);

	//assert(1.0 - cosO*cosO >= 0.0);

	sinO = 1.0 - cosO*cosO > 0.0 ? sqrt(1.0 - cosO*cosO) : 0.0;

	//if(sinO != sinO) endrun(4001);

	dvx= rmass*(-rvx + cosO*rvv[0] + sinO*rv*nperp[0]);
	dvy= rmass*(-rvy + cosO*rvv[1] + sinO*rv*nperp[1]);
	dvz= rmass*(-rvz + cosO*rvv[2] + sinO*rv*nperp[2]);

	if(dvx != dvx || dvy != dvy || dvz != dvz) {
	  endrun(4000);
	}

	//debug
	/*
	rvv[0]= cosO*rvv[0] + sinO*rv*nperp[0];
	rvv[1]= cosO*rvv[1] + sinO*rv*nperp[1];
	rvv[2]= cosO*rvv[2] + sinO*rv*nperp[2];
	rvv[0]= SidmDataIn[i].Vel[0] + dvx;
	rvv[1]= SidmDataIn[i].Vel[1] + dvy;
	rvv[2]= SidmDataIn[i].Vel[2] + dvz;
	fprintf(stderr, "%e %e\n", rv, norm(rvv));
	*/
#endif

	
        /* Scatter. Calc velocity change */

	// Better way of producing spherical random numbers
	// Sep 19, 2005
#if (CROSS_SECTION_TYPE < 4)
	// isotropic scattering
	random_direction(nx);
	dvx= rmass*(-rvx+rv*nx[0]);
	dvy= rmass*(-rvy+rv*nx[1]);
	dvz= rmass*(-rvz+rv*nx[2]);
#endif
	
        SidmDataResult[i].dv[0]= dvx;
        SidmDataResult[i].dv[1]= dvy;
        SidmDataResult[i].dv[2]= dvz;
        SidmDataConfirm[i].Task= ThisTask;
        
        break;
      }
    }  

    /* 2nd communicate contributions, and sum up */

    tstart=second();
    for(level=1; level<NTask; level++) {
      sendTask= ThisTask;
      recvTask= ThisTask ^ level; 
    
      MPI_Sendrecv(&SidmDataResult[noffset[recvTask]], 
		   nrecv[recvTask]*sizeof(struct sidmdata_out), MPI_BYTE,
		   recvTask, TAG_ANY, &SidmDataPartialResult[0],
		   nrecv[sendTask]*sizeof(struct sidmdata_out), MPI_BYTE, 
		   recvTask, TAG_ANY, MPI_COMM_WORLD, &status);

      for(i=0; i<nrecv[ThisTask]; i++) {
        SidmDataResult[noffset[ThisTask] + i].Ngb += 
	  SidmDataPartialResult[i].Ngb;
        
        // Keep First collision only
        if(SidmDataResult[noffset[ThisTask] + i].dv[0] == 0.0 &&
           SidmDataPartialResult[i].dv[0] != 0.0 ) {
          for(k=0; k<3; k++) {
            SidmDataResult[noffset[ThisTask] + i].dv[k] 
              = SidmDataPartialResult[i].dv[k];
          }
          SidmDataConfirm[noffset[ThisTask] + i].Task
            = recvTask;
        }
      }
    }
    tend=second();
    All.CPU_CommSum += timediff(tstart,tend);

    /* transfer the result to the particles */
      
    for(i=nstart, ncount=0, nexport=0, timelinecounter=startcounter; 
        timelinecounter<NumForceUpdate && ncount<nthis; 
        i=P[i].ForceFlag, timelinecounter++)
      if(P[i].Type > 0) {
        if(P[i].Type & 8) {
          place= noffset[ThisTask] + nexport; 
          nexport++;
          P[i].Type&= 7;
        }
        else
          place= nbuffer + (ncount-nexport);
        
        P[i].NgbVelDisp = SidmDataResult[place].Ngb;
        
        // Check # of neighbours
        if(P[i].NgbVelDisp < (All.DesNumNgb-All.MaxNumNgbDeviation) || 
	   (P[i].NgbVelDisp > (All.DesNumNgb+All.MaxNumNgbDeviation))) {
          // Scattering is invalid
          // Redo sidm in ensure_neighbours() function
          SidmDataConfirm[place].Task= -1;
          if(SidmDataResult[place].dv[0] != 0.0)
            nscat[2]++; // rejected;
        }
        else if(SidmDataResult[place].dv[0] != 0.0) {
          // OK. Update Velocity.
	  /* Oct 09, 2005
          P[i].Vel[0] += SidmDataResult[place].dv[0];
          P[i].Vel[1] += SidmDataResult[place].dv[1];
          P[i].Vel[2] += SidmDataResult[place].dv[2];
	  */
	  P[i].dVel[0] = SidmDataResult[place].dv[0];
          P[i].dVel[1] = SidmDataResult[place].dv[1];
          P[i].dVel[2] = SidmDataResult[place].dv[2];
          nscat[1]++; // scattered;
        }
	else {
	  // Feb 15,2006 Double scattering rejection (very rare)
          SidmDataConfirm[place].Task= -1;
	}
        ncount++;
      }
    
    /* Scattering Confirmation */
    /* Communication; 3rd time */

    tstart= second();      
    for(level=1; level<NTask; level++){
      sendTask = ThisTask;
      recvTask = ThisTask ^ level; 
      
      MPI_Sendrecv(&SidmDataConfirm[noffset[sendTask]], 
		   nrecv[sendTask]*sizeof(struct sidmdata_confirm), MPI_BYTE, 
		   recvTask, TAG_ANY, 
		   &SidmDataConfirm[noffset[recvTask]], 
		   nrecv[recvTask]*sizeof(struct sidmdata_confirm), MPI_BYTE, 
		   recvTask, TAG_ANY, MPI_COMM_WORLD, &status);
    }
    tend= second();
    All.CPU_CommSum += timediff(tstart, tend);
    
    /* Update the targets of active particles if confirmed */

    for(j=0; j<(nbuffer+ncount-nexport); j++) {
      if(SidmDataConfirm[j].Task == ThisTask) {
        if(SidmTarget[j] <= 0 || SidmTarget[j] > NumPart) {
          // for debug only
          printf("SIDM ERROR: SidmTarget is wrong\n");
          endrun(0);
        }
	// Oct 9,2005 Vel[] => dVel[] -=-> =-
        P[SidmTarget[j]].dVel[0] = -SidmDataResult[j].dv[0];
        P[SidmTarget[j]].dVel[1] = -SidmDataResult[j].dv[1];
        P[SidmTarget[j]].dVel[2] = -SidmDataResult[j].dv[2];
        
#ifdef SCATTERLOG
        /* Scatter Log */
	ScatLog.id1= SidmDataIn[j].ID;
	ScatLog.id2= P[SidmTarget[j]].ID;

	ScatLog.Hsml1= SidmDataIn[j].Hsml;
	ScatLog.Hsml2= P[SidmTarget[j]].HsmlVelDisp;

	ScatLog.x1[0]= SidmDataIn[j].Pos[0];
	ScatLog.x1[1]= SidmDataIn[j].Pos[1];
	ScatLog.x1[2]= SidmDataIn[j].Pos[2];

	ScatLog.x2[0]= P[SidmTarget[j]].PosPred[0];
	ScatLog.x2[1]= P[SidmTarget[j]].PosPred[1];
	ScatLog.x2[2]= P[SidmTarget[j]].PosPred[2];


	ScatLog.v1[0]= SidmDataIn[j].Vel[0];
	ScatLog.v1[1]= SidmDataIn[j].Vel[1];
	ScatLog.v1[2]= SidmDataIn[j].Vel[2];

	ScatLog.v2[0]= P[SidmTarget[j]].Vel[0];
	ScatLog.v2[1]= P[SidmTarget[j]].Vel[1];
	ScatLog.v2[2]= P[SidmTarget[j]].Vel[2];

	ScatLog.dv[0]= SidmDataResult[j].dv[0];
	ScatLog.dv[1]= SidmDataResult[j].dv[1];
	ScatLog.dv[2]= SidmDataResult[j].dv[2];

	fwrite(&ScatLog, sizeof(ScatLog), 1, fp);
#endif
      }
    }
    
    nstart= i; /* continue at this point in the timeline in next iteration */
    startcounter=timelinecounter;
      
    npleft-= ncount;
    ntotleft-= ntot;
  }

  // Summerize the scattering statistics
  MPI_Reduce(nscat, nscatTot, 3, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
#ifdef FINDNBRLOG
  if(ThisTask == 0){
    //printf("SIDM SCT tot= %d 1st= %d scattered= %d rejected= %d\n",   
    fprintf(stdout, "SCT %d %d %d %d\n",     
     ntot, nscatTot[0], nscatTot[1], nscatTot[2]);
  }
#endif

#ifdef SCATTERLOG
  fclose(fp);
#endif
  free(nrecv);
  free(noffset);
}
void random_unit_ball(point* p) {
	random_direction(p);
	real r = rand_one_sided();
	r = pow(r,p->n-1);
	(*p) *= r;
}
Beispiel #11
0
int main()
{
    sf::RenderWindow window(sf::VideoMode(2000, 1200), "Do not pop the balloons!");
    std::vector<MyCircle> shapes;

    int active_circles = NUMCIRCLES;
    auto size = window.getSize();

    for (int i=0; i < NUMCIRCLES; ++i) {
        MyCircle shape(&window);
        shape.setRadius(random_float(0.66*CIRCLERADIUS, 1.33*CIRCLERADIUS));
        shape.setPosition(random_float(0, shape.x_max), random_float(0, shape.y_max));
        shape.setFillColor(colours[random_int(0, colours.size()-1)]);
        //shape.setFillColor(sf::Color::Black);
        shape.setDirection(random_direction(), random_direction());
        shape.setSpeed(random_float(0, XSPEED), random_float(0, YSPEED));
        shapes.push_back(shape);
    }

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        window.clear(sf::Color::Yellow);
        for (int i=0; i < NUMCIRCLES; ++i) {
            auto pos = shapes[i].getPosition();
            auto rad = shapes[i].getRadius();
            auto x = pos.x;
            auto y = pos.y;

            //Get mouse click
            if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
                auto mouse_pos = sf::Mouse::getPosition(window);
                if (mouse_pos.x > x && mouse_pos.x < x + 2*rad &&
                    mouse_pos.y > y && mouse_pos.y < y + 2*rad) {
                    shapes[i].setFillColor(sf::Color::Transparent);
                    shapes[i].setRadius(0.f);
                    shapes[i].setSpeed(0.f, 0.f);
                    active_circles -= 1;

                    if (active_circles == 0) window.close();
                }
            }

            // From here is the code to make the ball bounce left to right
            if (x >= shapes[i].x_max) {
                shapes[i].x_direction = -1;
            }

            if (x <= 0) {
                shapes[i].x_direction = 1;
            }

            x += shapes[i].x_speed * shapes[i].x_direction;
            // End

            // Copy the above code, but swap Y for X to make the ball bounce up and down
            if (y >= shapes[i].y_max) {
                shapes[i].y_direction = -1;
            }

            if (y <= 0) {
                shapes[i].y_direction = 1;
            }

            y += shapes[i].y_speed * shapes[i].y_direction;

            shapes[i].setPosition(x, y);
            window.draw(shapes[i]);
        }
        window.display();
    }

    return 0;
}