Exemplo n.º 1
0
void find_parents(int64_t ngroups) {
  int64_t i, j, *halo_order = NULL;
  struct fast3tree_results *nearest;
  struct fast3tree *halo_tree;
  FAST3TREE_TYPE *h1, *h2;
  float max_dist = BOX_SIZE/2.01, range;

  halo_order = check_realloc(halo_order, sizeof(int64_t)*ngroups,
			     "Allocating halo order.");
  halo_tree = fast3tree_init(ngroups, GROUP_LIST);
  for (i=0; i<ngroups; i++) {
    GROUP_LIST[i].parent = -1;
    halo_order[i] = i;
  }
  qsort(halo_order, ngroups, sizeof(int64_t), sort_halo_order);

  nearest = fast3tree_results_init();
  for (i=0; i<ngroups; i++) {
    h1 = &(GROUP_LIST[halo_order[i]]);

    range = h1->RADIUS*RADIUS_CONVERSION;
    if (max_dist < range) range = max_dist;
    fast3tree_find_sphere_periodic(halo_tree, nearest, h1->pos, range);

    for (j=0; j<nearest->num_points; j++) {
      h2 = nearest->points[j];
      if (h2->RADIUS < h1->RADIUS) h2->parent = h1->id;
    }
  }
  fast3tree_results_free(nearest);
  fast3tree_free(&halo_tree);
  free(halo_order);
}
Exemplo n.º 2
0
static PyObject * uberseg_tree(PyObject* self, PyObject* args) {
  int x=0,y=0,k=0,segmin=0;
  float dmin=0,r=0,dx=0,d=0;
  float pos[2],fac=0;

  PyObject* seg = NULL;
  PyObject* weight = NULL;
  int Nx;
  int Ny;
  int object_number;
  PyObject* obj_inds_x = NULL;
  PyObject* obj_inds_y = NULL;
  int Ninds;
  int *ptrx,*ptry,*ptrs;
  float *ptrw;
  
  struct mytype *obj = NULL;
  struct fast3tree *tree = NULL;
  struct fast3tree_results *res = NULL;
  
  if (!PyArg_ParseTuple(args, (char*)"OOiiiOOi", &seg, &weight, &Nx, &Ny, &object_number, &obj_inds_x, &obj_inds_y, &Ninds)) {
    return NULL;
  }

  obj = (struct mytype *)malloc(sizeof(struct mytype)*Ninds);
  if(obj == NULL) exit(1);
  
  for(k=0;k<Ninds;++k) {
    ptrx = (int*)PyArray_GETPTR1(obj_inds_x,k);
    ptry = (int*)PyArray_GETPTR1(obj_inds_y,k);
    ptrs = (int*)PyArray_GETPTR2(seg,*ptrx,*ptry);
    obj[k].idx = k;
    obj[k].seg = *ptrs;
    obj[k].pos[0] = (float)(*ptrx);
    obj[k].pos[1] = (float)(*ptry);
  }
  
  tree = fast3tree_init(Ninds,obj);
  if(tree == NULL) exit(1);

  res = fast3tree_results_init();    
  if(res == NULL) exit(1);

  float maxr = 1.1*sqrt(Nx*Nx+Ny*Ny);
    
  for(x=0;x<Nx;++x) {
    for(y=0;y<Ny;++y) {
      
      //shortcuts
      ptrs = (int*)PyArray_GETPTR2(seg,x,y);
      if(*ptrs == object_number)
	continue;
      
      if(*ptrs > 0 && *ptrs != object_number) {
	ptrw = (float*)PyArray_GETPTR2(weight,x,y);
	*ptrw = 0.0;
	continue;
      }
      
      //must do search
      pos[0] = (float)x;
      pos[1] = (float)y;
      r = fast3tree_find_next_closest_distance(tree,res,pos);
      fac = 1.0/1.1;
      do {
	fac *= 1.1;
	fast3tree_results_clear(res);
	fast3tree_find_sphere(tree,res,pos,r*fac);
      } while(res->num_points == 0 && r*fac <= maxr);
      
      segmin = -1;
      for(k=0;k<res->num_points;++k) {
	dx = res->points[k]->pos[0]-x;
	d = dx*dx;
	dx = res->points[k]->pos[1]-y;
	d += dx*dx;
	if(segmin == -1 || d < dmin) {
	  segmin = res->points[k]->seg;
	  dmin = d;
	}
      }
      
      if(segmin == -1) {
	continue;
      }
      
      if(segmin != object_number) {
	ptrw = (float*)PyArray_GETPTR2(weight,x,y);
	*ptrw = 0.0;
      }
    }
  }

  free(obj);
  fast3tree_free(&tree);
  fast3tree_results_free(res);
 
  
  Py_INCREF(Py_None);
  return Py_None;
}
Exemplo n.º 3
0
/* special_step = 1 (first step), 0 (normal step), -1 (last step) */
void do_timestep(double a1, double a2, double a3, int special_step)
{
  int i,j;
  float dt = (scale_to_years(a3) - scale_to_years(a2))/1.0e6; //In Myr
  float old_dt = (scale_to_years(a2) - scale_to_years(a1))/1.0e6; //In Myr
  float range, av_a = (a2+a3)/2.0;
  float inv_rs, r,m, dx, dy, dz, r3, acc, rsoft2, inv_rs2, softening_factor;
  float dvx, dvy, dvz, vorb, coulomb, lnc, dens, rd;
  struct fast3tree_results *nearest;
  struct min_halo *h1, *h2;
  float vel_dt = dt * 1.02268944e-6 * h0 / av_a; //1 km/s to comoving Mpc/Myr/h
  float max_dist = box_size / 2.0;

  // 1 km/s / Myr to comoving Mpc/Myr^2/h 
  float acc_dt2 = (dt*dt / 2.0) * 1.02268944e-6 * h0 / av_a;
  float conv_const = av_a*av_a / h0 / h0;

  //Update intermediate velocities
  if (special_step != 1) { //If we're not at the first step.
    for (i=0; i<num_halos; i++) {
      h1 = &(halos[i]);
      for (j=0; j<3; j++) {
	h1->vel[j] += h1->a[j]*old_dt*0.5;
	h1->a[j] = 0;
      }
    }
  }

  if (special_step<0) return; //Return if this is the final step.

  //Calculate accelerations
  fast3tree_rebuild(halo_tree, num_halos, halos);
  set_tree_maxmin();
  nearest = fast3tree_results_init();

  for (i=0; i<num_halos; i++) {
    h1 = &(halos[i]);
    range = halo_grav_range(h1->mvir/h0, dt)*h0/av_a; //In comoving Mpc/h
    if (max_dist < range) range = max_dist*0.99;
    assert(fast3tree_find_sphere_periodic(halo_tree, nearest, h1->pos, range));

    if (!nearest->num_points)
	continue; //Skip if no close halos.

    inv_rs = 1.0/h1->rs; //In comoving h/Mpc
    for (j=0; j<nearest->num_points; j++) {
      //Calculate gravitational forces
      h2 = nearest->points[j];
#define DIST(a,b) a = h1->b - h2->b; \
      if (a > max_dist) a-=box_size; \
      else if (a < -max_dist) a+=box_size;
      DIST(dx,pos[0]);
      DIST(dy,pos[1]);
      DIST(dz,pos[2]);
#undef DIST
      r = sqrtf(dx*dx + dy*dy + dz*dz); // in comoving Mpc/h

      //Including acorr slightly improves velocity results
      // as a function of redshift.
      m = h1->mass_factor*ff_cached(r*inv_rs); //In Msun

      //Apply force softening:
      rsoft2 = r*r + h2->rvir*h2->rvir*1.0e-6;
      r3 = rsoft2 * r * conv_const; //in (real Mpc)^2 * (comoving Mpc/h)
      acc = r ? Gc*m/r3 : 0; //In km/s / Myr / (comoving Mpc/h)

      h2->a[0] += acc*dx;      //In km/s / Myr
      h2->a[1] += acc*dy;
      h2->a[2] += acc*dz;
      if (h2->id == 12) {
	print_halo(i);
	printf("R: %f Acc: %e Dx: %f Dy: %f Dz: %f\n", r, acc, dx, dy, dz);
      }
    }
  }
  fast3tree_results_free(nearest);

  //Update halo velocities
  if (special_step != 1) { //If not at the first step
    for (i=0; i<num_halos; i++) {
      h1 = &(halos[i]);
      for (j=0; j<3; j++) h1->vel[j] += h1->a[j]*dt*0.5;
    }
  }

  //Calculate new positions
  for (i=0; i<num_halos; i++) {
    h1 = &(halos[i]);
    for (j=0; j<3; j++) {
      h1->pos[j] += h1->vel[j]*vel_dt + h1->a[j]*acc_dt2;
      if (h1->pos[j] < 0) h1->pos[j] += box_size;
      if (h1->pos[j] > box_size) h1->pos[j] -= box_size;
    }
    if (h1->id == 12) print_halo(i);
  }
  printf("\n");
}