Example #1
0
void fold_all ( void ) {
  int i ;
  for (i = 0 ; i < n_total_particles ; i++) {
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,xdir);
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,ydir);
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,zdir);
  }
}
//calculates average density profile in dir direction over last n_conf configurations
void density_profile_av(int n_conf, int n_bin, double density, int dir, double *rho_ave, int type)
{
  int i,j,k,m,n;
  double r;
  double r_bin;
  double pos[3];
  int  image_box[3];
  
  //calculation over last n_conf configurations  
  
  //bin width
  r_bin = box_l[dir]/(double)(n_bin);
  
  for (i=0; i<n_bin; i++)
    rho_ave[i]=0;
  
  k=n_configs-n_conf;
  
  while(k<n_configs) {
    r = 0;
    j = 0;
    while (r < box_l[dir]) { 
      n = 0;
      for(i=0; i<n_part; i++) {
	//com particles
	if(partCfg[i].p.type == type) {
	  for(m=0; m<3; m++) {
	    pos[m] = configs[k][3*i+m];
	    image_box[m] = 0;
	  }
	  fold_coordinate(pos, image_box, dir);
	  if (pos[dir] <= r+r_bin && pos[dir] > r)
	    n++;
	}
      }
      
      rho_ave[j] += (double)(n)/(box_l[1]*box_l[2]*r_bin)/density;
      j++;
      r += r_bin;
    }     
    k++;
  } //k loop
  
  // normalization
  for (i=0; i<n_bin; i++)
    rho_ave[i]/=n_conf;
}
int calc_radial_density_map (int xbins,int ybins,int thetabins,double xrange,double yrange, double axis[3], double center[3], IntList *beadids, DoubleList *density_map, DoubleList *density_profile) {
  int i,j,t;
  int pi,bi;
  int nbeadtypes;
  int beadcount;
  double vectprod[3];
  double pvector[3];
  double xdist,ydist,rdist,xav,yav,theta;
  double xbinwidth,ybinwidth,binvolume;
  double thetabinwidth;
  double *thetaradii;
  int *thetacounts;
  int xindex,yindex,tindex;
  xbinwidth = xrange/(double)(xbins);
  ybinwidth = yrange/(double)(ybins);

  nbeadtypes = beadids->n;
  /* Update particles */
  updatePartCfg(WITHOUT_BONDS);

  /*Make sure particles are folded  */
  for (i = 0 ; i < n_part ; i++) {
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,0);
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,1);
    fold_coordinate(partCfg[i].r.p,partCfg[i].l.i,2);
  }

  beadcount = 0;
  xav = 0.0;
  yav = 0.0;
  for ( pi = 0 ; pi < n_part ; pi++ ) {
    for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
      if ( beadids->e[bi] == partCfg[pi].p.type ) {


	/* Find the vector from the point to the center */
	vecsub(center,partCfg[pi].r.p,pvector);

	/* Work out x and y coordinates with respect to rotation axis */
	
	/* Find the minimum distance of the point from the axis */
	vector_product(axis,pvector,vectprod);
	xdist = sqrt(sqrlen(vectprod)/sqrlen(axis));

	/* Find the projection of the vector from the point to the center
	   onto the axis vector */
	ydist = scalar(axis,pvector)/sqrt(sqrlen(axis));
	
    
	/* Work out relevant indices for x and y */
	xindex = (int)(floor(xdist/xbinwidth));
	yindex = (int)(floor((ydist+yrange*0.5)/ybinwidth));
	/*
	printf("x %d y %d \n",xindex,yindex);
	printf("p %f %f %f \n",partCfg[pi].r.p[0],partCfg[pi].r.p[1],partCfg[pi].r.p[2]);
	printf("pvec %f %f %f \n",pvector[0],pvector[1],pvector[2]);
	printf("axis %f %f %f \n",axis[0],axis[1],axis[2]);
	printf("dists %f %f \n",xdist,ydist);
	fflush(stdout);
	*/
	/* Check array bounds */
	if ( (xindex < xbins && xindex > 0) && (yindex < ybins && yindex > 0) ) {
	  density_map[bi].e[ybins*xindex+yindex] += 1;
	  xav += xdist;
	  yav += ydist;
	  beadcount += 1;
	} else {
	  //	    fprintf(stderr,"ERROR: outside array bounds in calc_radial_density_map"); fflush(NULL); errexit(); 
	}
      }

    }
  }


  /* Now turn counts into densities for the density map */
  for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
    for ( i = 0 ; i < xbins ; i++ ) {
      /* All bins are cylinders and therefore constant in yindex */
      binvolume = PI*(2*i*xbinwidth + xbinwidth*xbinwidth)*yrange;
      for ( j = 0 ; j < ybins ; j++ ) {
	density_map[bi].e[ybins*i+j] /= binvolume;
      }
    }
  }


  /* if required calculate the theta density profile */
  if ( thetabins > 0 ) {
    /* Convert the center to an output of the density center */
    xav = xav/(double)(beadcount);
    yav = yav/(double)(beadcount);
    thetabinwidth = 2*PI/(double)(thetabins);
    thetaradii = (double*)malloc(thetabins*nbeadtypes*sizeof(double));
    thetacounts = (int*)malloc(thetabins*nbeadtypes*sizeof(int));
    for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
      for ( t = 0 ; t < thetabins ; t++ ) {
	thetaradii[bi*thetabins+t] = 0.0;
	thetacounts[bi*thetabins+t] = 0.0;
      }
    }
    /* Maybe there is a nicer way to do this but now I will just repeat the loop over all particles */
      for ( pi = 0 ; pi < n_part ; pi++ ) {
	for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
	  if ( beadids->e[bi] == partCfg[pi].p.type ) {
	    vecsub(center,partCfg[pi].r.p,pvector);
	    vector_product(axis,pvector,vectprod);
	    xdist = sqrt(sqrlen(vectprod)/sqrlen(axis));
	    ydist = scalar(axis,pvector)/sqrt(sqrlen(axis));
	    /* Center the coordinates */

	    xdist = xdist - xav;
	    ydist = ydist - yav;
	    rdist = sqrt(xdist*xdist+ydist*ydist);
	    if ( ydist >= 0 ) {
	      theta = acos(xdist/rdist);
	    } else {
	      theta = 2*PI-acos(xdist/rdist);
	    }
	    tindex = (int)(floor(theta/thetabinwidth));
	    thetaradii[bi*thetabins+tindex] += xdist + xav;
	    thetacounts[bi*thetabins+tindex] += 1;
	    if ( tindex >= thetabins ) {
	      fprintf(stderr,"ERROR: outside density_profile array bounds in calc_radial_density_map"); fflush(NULL); errexit(); 
	    } else {
	      density_profile[bi].e[tindex] += 1;
	    }
	  }	  
	}
      }



      /* normalize the theta densities*/
      for ( bi = 0 ; bi < nbeadtypes ; bi++ ) {
	for ( t = 0 ; t < thetabins ; t++ ) {
	  rdist = thetaradii[bi*thetabins+t]/(double)(thetacounts[bi*thetabins+t]);
	  density_profile[bi].e[t] /= rdist*rdist;
	}
      }
       


      free(thetaradii);
      free(thetacounts);

  }
  






  //  printf("done \n");
  return ES_OK;
}
void calc_diffusion_profile(int dir, double xmin, double xmax, int nbins, int n_part, int n_conf, int time, int type, double *bins) 
{
  int i,t, count,index;
  double tcount=0;
  double xpos;
  double tpos[3];
  int img_box[3] = {0,0,0};
  //double delta_x = (box_l[0])/((double) nbins);
  
  /* create and initialize the array of bins */
  
  // double *bins;
  
  int *label;
  label = (int*)malloc(n_part*sizeof(int));
  
  /* calculation over last n_conf configurations */
  t=n_configs-n_conf;
  
  while (t<n_configs-time) {
    /* check initial condition */
    count = 0;
    
    for (i=0;i<n_part;i++) {
      if(partCfg[i].p.type == type) {
	tpos[0] = configs[t][3*i];
	tpos[1] = configs[t][3*i+1];
	tpos[2] = configs[t][3*i+2];
	fold_coordinate(tpos, img_box,dir);
	xpos = tpos[dir];
	if(xpos > xmin && xpos < xmax) {
	  label[count] = i;
	}
	else label[count] = -1;
	count ++;
      }
    }
    
    /* check at time 'time' */
    for (i=0;i<n_part;i++) {
      if (label[i]>0) {
	tpos[0] = configs[t+time][3*label[i]];
	tpos[1] = configs[t+time][3*label[i]+1];
	tpos[2] = configs[t+time][3*label[i]+2];
	fold_coordinate(tpos, img_box,dir);
	xpos = tpos[dir];
	
	index = (int)(xpos/box_l[dir]*nbins);
	bins[index]++;
      }
    }
    t++;
    tcount++;
  }
  
  /* normalization */
  for (i=0;i<nbins;i++) {
    bins[i]=bins[i]/(tcount);
  }
  free(label);
}
Example #5
0
int calc_cylindrical_average(std::vector<double> center, std::vector<double> direction, double length,
                             double radius, int bins_axial, int bins_radial, std::vector<int> types,
                             std::map<std::string, std::vector<std::vector<std::vector<double> > > > &distribution)
{
  int index_axial;
  int index_radial;
  double binwd_axial  = length / bins_axial;
  double binwd_radial = radius / bins_radial;

  // Select all particle types if the only entry in types is -1
  bool all_types = false;
  if (types.size() == 1 && types[0] == -1) all_types = true;

  distribution.insert( std::pair<std::string, std::vector<std::vector<std::vector<double> > > >
                                ("density",   std::vector<std::vector<std::vector<double> > >(types.size())) );
  distribution.insert( std::pair<std::string, std::vector<std::vector<std::vector<double> > > >
                                ("v_r",       std::vector<std::vector<std::vector<double> > >(types.size())) );
  distribution.insert( std::pair<std::string, std::vector<std::vector<std::vector<double> > > >
                                ("v_t",       std::vector<std::vector<std::vector<double> > >(types.size())) );

  for (unsigned int type = 0; type < types.size(); type++) {
    distribution["density"][type].resize(bins_radial);
        distribution["v_r"][type].resize(bins_radial);
        distribution["v_t"][type].resize(bins_radial);
    for (int index_radial = 0; index_radial < bins_radial; index_radial++) {
      distribution["density"][type][index_radial].assign(bins_axial, 0.0);
          distribution["v_r"][type][index_radial].assign(bins_axial, 0.0);
          distribution["v_t"][type][index_radial].assign(bins_axial, 0.0);
    }
  }

  // Update particles
  updatePartCfg(WITHOUT_BONDS);

  // Make sure particles are folded
  for (int i = 0 ; i < n_part ; i++) {
    fold_coordinate(partCfg[i].r.p,partCfg[i].m.v,partCfg[i].l.i,0);
    fold_coordinate(partCfg[i].r.p,partCfg[i].m.v,partCfg[i].l.i,1);
    fold_coordinate(partCfg[i].r.p,partCfg[i].m.v,partCfg[i].l.i,2);
  }

  // Declare variables for the density calculation
  double height, dist, v_radial, v_axial;
  double norm_direction = utils::veclen(direction);
  std::vector<double> pos(3), vel(3), diff, hat;

  for (int part_id = 0; part_id < n_part; part_id++) {
    for (unsigned int type_id = 0; type_id < types.size(); type_id++) {
      if ( types[type_id] == partCfg[part_id].p.type || all_types) {
        pos[0] = partCfg[part_id].r.p[0];
        pos[1] = partCfg[part_id].r.p[1];
        pos[2] = partCfg[part_id].r.p[2];
        vel[0] = partCfg[part_id].m.v[0];
        vel[1] = partCfg[part_id].m.v[1];
        vel[2] = partCfg[part_id].m.v[2];

        // Find the vector from center to the current particle
        diff = utils::vecsub(pos,center);

        // Find the height of the particle above the axis (height) and
        // the distance from the center point (dist)
        hat    = utils::cross_product(direction,diff);
        height = utils::veclen(hat);
        dist   = utils::dot_product(direction,diff) / norm_direction;

        // Determine the components of the velocity parallel and
        // perpendicular to the direction vector
        if ( height == 0 )
          v_radial = utils::veclen(utils::cross_product(vel,direction)) / norm_direction;
        else
          v_radial = utils::dot_product(vel,hat) / height;
        v_axial  = utils::dot_product(vel,direction) / norm_direction;
        
        // Work out relevant indices for x and y
        index_radial = static_cast<int>( floor(height / binwd_radial) );
        index_axial  = static_cast<int>( floor((dist + 0.5*length) / binwd_axial) );

        if ( (index_radial < bins_radial && index_radial >= 0) &&
             (index_axial  < bins_axial  && index_axial  >= 0) ) {
          distribution["density"][type_id][index_radial][index_axial] += 1;
          distribution["v_r"][type_id][index_radial][index_axial] += v_radial;
          distribution["v_t"][type_id][index_radial][index_axial] += v_axial;
        }
      }
    }
  }

  // Now we turn the counts into densities by dividing by one radial
  // bin (binvolume).  We also divide the velocites by the counts.
  double binvolume;
  for (unsigned int type_id = 0; type_id < types.size(); type_id++) {
    for (int index_radial = 0 ; index_radial < bins_radial ; index_radial++) {
      // All bins are cylindrical shells of thickness binwd_radial.
      // The volume is thus: binvolume = pi*(r_outer - r_inner)^2 * length
      if ( index_radial == 0 )
        binvolume = M_PI * binwd_radial*binwd_radial * length;
      else
        binvolume = M_PI * (index_radial*index_radial + 2*index_radial) * binwd_radial*binwd_radial * length;
      for (int index_axial = 0 ; index_axial < bins_axial ; index_axial++) {
        if ( distribution["density"][type_id][index_radial][index_axial] != 0 ) {
          distribution["v_r"][type_id][index_radial][index_axial] /= distribution["density"][type_id][index_radial][index_axial];
          distribution["v_t"][type_id][index_radial][index_axial] /= distribution["density"][type_id][index_radial][index_axial];
          distribution["density"][type_id][index_radial][index_axial] /= binvolume;
        }
      }
    }
  }

  return ES_OK;
}